【问题标题】:Possible to create Python multiprocessing child/worker processes that do not import the __main__ module?可以创建不导入 __main__ 模块的 Python 多处理子/工作进程吗?
【发布时间】:2019-10-23 12:43:54
【问题描述】:

Windows 上multiprocessingstandard behavior 是在生成时将__main__ 模块导入子进程。

对于有很多导入的大型项目,这会显着减慢子进程的启动速度,更不用说消耗的额外资源了。对于子进程将运行仅使用一小部分导入的自包含任务的情况,这似乎非常低效。

有没有办法明确指定子进程的导入?如果不是多处理库,是否有替代方案?

虽然我对 Python 3 特别感兴趣,但 Python 2 的答案可能对其他人有用。


编辑

我已确认approach suggested by Lie Ryan 有效,如下例所示:

import sys
import types

def imports():
    for name, val in globals().items():
        if isinstance(val, types.ModuleType):
            yield val.__name__

def worker():
    print('Worker modules:')
    print('\n'.join(imports()))

if __name__ == '__main__':
    import multiprocessing

    print('Main modules:')
    print('\n'.join(imports()))
    print()

    p = multiprocessing.Process(target=worker)
    p.start()
    p.join()

输出:

Main modules:
builtins
sys
types
multiprocessing

Worker modules:
sys
types

但是,我认为我不能仅仅为了在代码库深处启用一个小功能而将顶级脚本包装在 if __name__ == '__main__' 中向团队的其他成员推销。仍然希望有一种方法可以在不进行顶层更改的情况下做到这一点。

【问题讨论】:

    标签: python python-3.x windows multiprocessing


    【解决方案1】:

    您链接的文档告诉您:

    确保新的 Python 解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)。

    ...
    

    应该使用if __name__ == '__main__': 来保护程序的“入口点”,如下所示:

    ...
    

    您也可以将 import 语句放在 if 块中,然后这些 import 语句将仅在您将 __main__.py 作为程序运行时执行,而不是在导入 __main__.py 时执行。


    <flame>要么选择要么改用支持真正fork()-ing的真正操作系统</flame>

    【讨论】:

    • 我相当肯定 NT 内核确实支持“真正的 fork()ing”,因为 Windows 曾一度符合 POSIX。只是 Win32 用户空间与这类事情非常不兼容,因此 NT 内核目前(?)没有为分叉进程公开一个“合理的”接口。
    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 2012-12-19
    • 1970-01-01
    • 2014-11-21
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多