多处理器池在某些运行中丢失变量值



我有类似的代码:

import multiprocessing
const = "ABC"
val_list = [1, 2, 3]
args = [{"val": val, "const": const} for val in val_list]

with multiprocessing.Pool() as p:
p.map(functionWrapper, args)

当我运行一个长的val_list,例如2000个条目时,那么对于一些多处理运行,val变量变成"val"而不是数字,或者const变量变成"const"而不是"ABC"。为什么会发生这种情况,我该如何阻止它?特别奇怪的是,val的问题只发生在我在Docker中运行代码时,而const的问题只出现在我在VSCode调试器中运行时,所以这看起来像是多处理的内存分配问题。当我在没有多处理的情况下按顺序运行val_list时,我不会出现错误。

您解释了给定的args类似

[{'val': 1, 'const': 'ABC'},
{'val': 2, 'const': 'ABC'},
{'val': 3, 'const': 'ABC'}]

偶尔functionWrapper会意外地接收文字字符串'const''val'作为输入参数。

那太糟糕了。

我们想知道这些文字是从哪里来的。做改为'konst'的实验大概会在bug输出中显示这个新字符串。

让我们想想游泳池的动作。它序列化了args列表,并发送了其中的一部分以进行反序列化和处理。关于您的生产设置比这里发布的漂亮的简单代码更复杂。我不确定你的val都是数字。想象一下它们是混合类型的,甚至它们都是字符串。

如果序列化程序/反序列化程序没有正确往返列出带有疯狂unicode字符串的元素,或其他数据类型,那么它就有可能不同步。当通过CSV文件格式往返数据帧,其中转义换行符和分隔符并不完全有效。听起来有点牵强,但这是一个可行的理论。

此外,数据值大于4 KiB管道缓冲区大小应该可以正常工作,但可能会暴露出异常的同步定时行为

再往前走,也许有什么东西在比赛并且正在设法从孩子正在读书的烟斗。验证您的生产代码没有任何代码试图以这种方式进行交互。把它归结为更简单和和更简单的测试用例,仍然比什么更复杂你发帖,直到症状不再显现。

这都是推测性的,但它指出了可以以确认/拒绝可能的故障模式。

您似乎以正确的方式使用了池——应该可以将此类数据值发送到工作进程。这是使用多处理模块的正常方式。

早或晚、早或晚执行初始化工人是派生出来的,这是这个模块的一个典型问题。您可以先open(),然后fork(),然后打开文件在父母和孩子身上。有时对懒散地推迟这样的动作直到孩子开始之后,因此每个孩子都有自己到文件的私有连接。


动作项目:

不是串行化感兴趣的大容量数据,保留该数据并只传递行ID或文件名孩子们用它来取回批量数据本身。做那个实验会帮助您更好地了解故障模式和每个触发它的环境细节。

祝你好运!

最新更新