当mutiprocessing使用fork作为启动方法时,为什么传递给Pool.map的函数会被pickle?

2024-09-27 21:30:33 发布

您现在位置:Python中文网/ 问答频道 /正文

在Linux中,multiprocesing模块使用fork作为新进程的默认启动方法。那么为什么需要pickle传递给map的函数呢?据我所知,进程的所有状态都已克隆,包括函数。我可以想象,如果使用spawn而不是fork,为什么这是必要的


Tags: 模块方法函数map进程linux状态fork
1条回答
网友
1楼 · 发布于 2024-09-27 21:30:33

.map()这样的作业方法不会启动新流程,因此此时利用fork将不是一种选择Pool使用IPC将参数传递给已经运行的工作进程,这始终需要序列化(pickle)。不过,似乎对这里的酸洗有更深层次的误解

当您查看像.map()这样的作业方法时,这里对函数的pickle只会导致限定函数名获得send as string,而取消pickle期间的接收过程基本上只会在其全局范围内查找函数以再次引用它

现在,在spawn和fork之间是一个差异,但它已经在工作进程启动时实现(从初始化Pool开始)。使用spawn-context,新工作人员需要从头构建所有可访问的全局对象,使用fork它们已经存在。因此,当您使用fork时,您的函数在引导过程中克隆一次,这将节省一点时间

当您稍后开始发送作业时,在worker中取消勾选已发送函数(使用任何上下文),只意味着再次从全局范围重新引用该函数。这就是为什么在实例化池和启动worker之前,函数需要存在,即使是用于spawn上下文

因此,无法pickle本地或未命名函数(lambda)可能会给您带来不便,其根源在于重新获取对工作进程中已经存在的函数的引用。如果以前使用spawn或fork来设置工作进程,那么在这一点上没有什么区别

相关问题 更多 >

    热门问题