【问题标题】:Preventing pool processes from importing __main__ and globals防止池进程导入 __main__ 和全局变量
【发布时间】:2011-05-10 23:47:01
【问题描述】:

我正在使用一个多处理工作人员池作为更大应用程序的一部分。因为我用它来处理大量的简单数学,所以我有一个无共享的架构,其中工作人员需要的唯一变量作为参数传递。因此,我不需要工作子进程来导入任何全局变量、我的 __main__ 模块或因此导入的任何模块。有没有办法强制这种行为并避免在生成池时影响性能?

我应该注意到我的环境是 Win32,它缺少 os.fork() 并且工作进程是使用子进程调用 sys.executable(即启动一个新的 Python 进程)生成的,然后序列化所有全局变量,并通过管道发送。” 根据this SO post。话虽这么说,我想尽可能少地做上述事情,这样我的游泳池打开得更快。

有什么想法吗?

【问题讨论】:

    标签: python multiprocessing


    【解决方案1】:

    查看multiprocessing.forking 实现,尤其是get_preparation_dataprepare(特定于win32),全局变量并没有被腌制。父进程的__main__ 的重新导入有点丑陋,但它不会运行除顶层代码之外的任何代码;甚至没有if __name__ == '__main__' 子句。所以只保留主模块没有导入时的副作用。


    您也可以在子进程启动时阻止您的主模块导入任何内容(仅在 win32 上有用,正如您所指出的,它不能分叉)。将 main() 及其导入移动到单独的模块中,以便启动脚本仅包含:

    if '__name__' == '__main__':
        from mainmodule import main
        main()
    

    子进程启动中还有隐含的import site。它做了重要的初始化,我不认为 mp.forking 有一个简单的方法来禁用它,但我不认为它会很昂贵。

    【讨论】:

    • 你说的是真的,将你的主要代码放在__name__ == '__main__' 子句中是不言而喻的,但是 必须 是一种明确的方式或至少是一组最佳方式减少子流程启动时间的做法。
    • @kaloyan 我认为您没有太多需要减少的地方;但我还添加了一件不言而喻的事情,那就是您也可以使用该子句保护导入。
    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多