Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用多处理时遇到的问题_Python_Python 3.x_Multiprocessing - Fatal编程技术网

Python 使用多处理时遇到的问题

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

我目前正在用Python 3.5.2编写一个测试运行程序,并为并行测试执行实现多处理。这是我第一次真正使用任何类型的多重处理,并试图解决问题,使其正常工作

如果您查看下面的
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绑定时使用线程,否则使用进程。