multiprocessing.Process在哪里

1 投票
2 回答
1237 浏览
提问于 2025-04-18 14:41

我正在把一个在Python 3.3上能正常运行的应用程序移植到3.4版本,但遇到了一个奇怪的情况。在从python.org下载的文件中,我找不到类multiprocessing.Process。相反,在multiprocessing.process模块中,我发现了一个叫做multiprocessing.process.BaseProcess的类。我能找到的关于旧的Process类的唯一痕迹是在新的multiprocessing.context模块中,multiprocessing.context.Process基本上是BaseProcess的一个封装函数。Python 3.4的文档中没有提到这些内容。有没有人能告诉我这是怎么回事,并指点我一些相关的文档?

2 个回答

1

它仍然存在,只是定义方式变得很不一样:

multiprocessing/__init__.py 现在以这样的方式给顶层包添加属性:

#
# Copy stuff from default context
#

globals().update((name, getattr(context._default_context, name))
                 for name in context._default_context.__all__)
__all__ = context._default_context.__all__

所以它是从 context._default_context 中提取 __all__

如果你查看 context.py,你会发现一个 Process 类:

#
# Type of default context -- underlying context can be set at most once
#

class Process(process.BaseProcess):
    _start_method = None
    @staticmethod
    def _Popen(process_obj):
        return _default_context.get_context().Process._Popen(process_obj)

而且里面还有更多具体的实现被引用和定义:

class ForkProcess(process.BaseProcess):
    _start_method = 'fork'
    @staticmethod
    def _Popen(process_obj):
        from .popen_fork import Popen
        return Popen(process_obj)

class SpawnProcess(process.BaseProcess):
    _start_method = 'spawn'
    @staticmethod
    def _Popen(process_obj):
        from .popen_spawn_posix import Popen
        return Popen(process_obj)

class ForkServerProcess(process.BaseProcess):
    _start_method = 'forkserver'
    @staticmethod
    def _Popen(process_obj):
        from .popen_forkserver import Popen
        return Popen(process_obj)

class ForkContext(BaseContext):
    _name = 'fork'
    Process = ForkProcess

class SpawnContext(BaseContext):
    _name = 'spawn'
    Process = SpawnProcess

class ForkServerContext(BaseContext):
    _name = 'forkserver'
    Process = ForkServerProcess
    def _check_available(self):
        from . import reduction
        if not reduction.HAVE_SEND_HANDLE:
            raise ValueError('forkserver start method not available')

_concrete_contexts = {
    'fork': ForkContext(),
    'spawn': SpawnContext(),
    'forkserver': ForkServerContext(),
}

_default_context = DefaultContext(_concrete_contexts['fork'])

默认上下文的 __all__ 会稍后设置:

DefaultContext.__all__ = list(x for x in dir(DefaultContext) if x[0] != '_')

代码布局的变化是为了支持 上下文。对于大多数人来说,这个变化应该是透明的,但任何从顶层包外部导入类的人(比如 from multiprocessing.queues import Queuefrom multiprocessing.process import Process)会发现他们的代码出现问题。

3

如果你在使用Eclipse和PyDev的话,你需要把'multiprocessing'这个模块强制加入到Python解释器的内置模块里。

撰写回答