Python 使用多处理时遇到的问题
我目前正在用Python 3.5.2编写一个测试运行程序,并为并行测试执行实现多处理。这是我第一次真正使用任何类型的多重处理,并试图解决问题,使其正常工作 如果您查看下面的Python 使用多处理时遇到的问题,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,我目前正在用Python 3.5.2编写一个测试运行程序,并为并行测试执行实现多处理。这是我第一次真正使用任何类型的多重处理,并试图解决问题,使其正常工作 如果您查看下面的run方法,您可以看到我正在使用mp.Pool和Pool.map通过self.\u run\u spec运行测试。这实际上效果很好。我面临的问题是,self.\u run\u spec接收的是插件的副本,而不是实际的实例。这使得原始插件实例保持不变 我知道这是一个基于流程工作方式的限制,但不确定如何更改实现以解决此问题 imp
run
方法,您可以看到我正在使用mp.Pool
和Pool.map
通过self.\u run\u spec
运行测试。这实际上效果很好。我面临的问题是,self.\u run\u spec
接收的是插件的副本,而不是实际的实例。这使得原始插件实例保持不变
我知道这是一个基于流程工作方式的限制,但不确定如何更改实现以解决此问题
import sys
from typing import cast, List, Dict, Any
from seleniumspec.spec import Spec, SpecContext
import traceback
import multiprocessing as mp
from functools import partial
from seleniumspec.plugin import *
class Runner(object):
specs = []
run_specs = []
plugins = cast(List[Plugin], [])
def add_specs(self, specs: List[Spec]):
[self.add_spec(spec) for spec in specs]
def add_spec(self, spec: Spec):
self.specs.append(spec)
for param in spec.params:
self.run_specs.append({'spec': spec, 'param': param})
def add_plugins(self, plugins: List[Plugin]):
[self.add_plugin(plugin) for plugin in plugins]
def add_plugin(self, plugin: Plugin):
self.plugins.append(plugin)
def run(self):
runner_start_event = RunnerStartPluginEvent(runner=self)
runner_stop_event = RunnerStopPluginEvent(runner=self)
# Hook: Runner Start
for plugin in self.plugins:
plugin.runner_start(runner_start_event)
# Run Tests in Parallel
p = mp.Pool(2)
p.map(partial(self._run_spec, plugins=self.plugins), self.run_specs)
# Hook: Runner Stop
for plugin in self.plugins:
plugin.runner_stop(runner_stop_event)
@staticmethod
def _run_spec(run_spec, plugins=None):
spec = run_spec['spec']
param = run_spec['param']
spec_context = SpecContext()
spec_context.param = param
spec_start_event = SpecStartPluginEvent(spec=spec, context=spec_context)
spec_stop_event = SpecStopPluginEvent(spec=spec, context=spec_context)
spec_fail_event = SpecFailPluginEvent(spec=spec, context=spec_context)
# Hook: Spec Start
for plugin in plugins:
plugin.spec_start(spec_start_event)
# Hook: Spec Setup
for spec_hook in spec.setup_hooks:
spec_hook(context=spec_context)
for i, step in enumerate(spec.steps):
step_start_event = StepStartPluginEvent(step=step)
step_stop_event = StepStopPluginEvent(step=step)
try:
# Hook: Step Start
for plugin in plugins:
plugin.step_start(step_start_event)
try:
step.fn(context=spec_context)
except AssertionError as e:
raise
# Hook: Step Stop
for plugin in plugins:
plugin.step_stop(step_stop_event)
except AssertionError as e:
error = traceback.format_exc()
spec_fail_event.error = error
# Hook: Spec Fail
for plugin in plugins:
plugin.spec_fail(spec_fail_event)
break
# Hook: Spec Teardown
for spec_hook in spec.teardown_hooks:
spec_hook(context=spec_context)
# Hook: Spec Stop
for plugin in plugins:
plugin.spec_stop(spec_stop_event)
return True
使用
多处理
而不使用多线程
的任何特殊原因?没有。这是我第一次做多进程/线程并使用多进程,因为这是我所看到的建议。多进程被鼓励用于不同的事情,主要是因为在Python2中,多线程并没有使用所有的核心,但是对于线程,您将使用相同的“内存空间”并将共享实例,而不是副本,在Python3中,核心问题得到了解决。看一看,如果你认为它合适的话,我可以扩展它作为一个正确的答案。CPython中的线程根本无法利用多核。当工作类型为IO绑定时使用线程,否则使用进程。