为啥在 Python 多处理中将 start 方法从“fork”更改为“spawn”不再允许我运行我的工作?

Posted

技术标签:

【中文标题】为啥在 Python 多处理中将 start 方法从“fork”更改为“spawn”不再允许我运行我的工作?【英文标题】:Why changing start method to 'spawn' from 'fork' in Python multiprocessing does not allow me run my job anymore?为什么在 Python 多处理中将 start 方法从“fork”更改为“spawn”不再允许我运行我的工作? 【发布时间】:2018-09-12 05:08:12 【问题描述】:

我可以使用multiprocessing.Process 和启动方法fork 运行后台函数。出于某种原因,我需要这个子进程在运行时启动一个新环境。所以我通过multiprocessing.set_start_method('spawn')将启动方法设置为spawn并通过job.start()运行作业我收到以下错误:

Can't pickle <class 'module'>: attribute lookup module on builtins failed

但是,我不会将 pickle 用于我正在调用的函数中的任何内容。我可能做错了什么?在spawn 模式下运行进程时,我应该遵循一般的经验法则吗?

仅供参考:我在一台装有 Ubuntu 16.04 的机器上

【问题讨论】:

multiprocessing 使用pickle 在进程之间传输数据。在“生成”模式下,这是任何数据进入进程的唯一方式; “fork”至少允许共享预先生成的数据而不被腌制。我猜你正在使用某种动态定义的类,这会给酸洗带来困难。 坚持Process 类中的基本类型以及它运行的任何函数/参数。让该函数调用一个不同的函数,该函数自己导入花哨的东西。 【参考方案1】:

有没有一般的经验法则...

是的。您遇到了这个记录在案的限制:

https://docs.python.org/3/library/multiprocessing.html

有一些额外的限制不适用于分叉启动方法。

更易腌制

确保 Process.init() 的所有参数都是可提取的。此外,如果您将 Process 子类化,请确保在调用 Process.start 方法时实例是可挑选的。

你在 ubuntu 上运行,所以fork 可能是正确的答案。如果您需要解决与 fork 不兼容的要求,那么您需要清楚地记录详细信息,作为选择改进解决方案的第一部分。

【讨论】:

以上是关于为啥在 Python 多处理中将 start 方法从“fork”更改为“spawn”不再允许我运行我的工作?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 多处理中将 Pool.map 与共享内存数组结合起来

在 Python 中测量多线程代码的处理时间

为啥在python里推荐使用多进程而不是多线程

为啥多处理不能并行工作? [复制]

在python中将日期转换为列表

为啥在windows上使用python多处理时打印三遍?