我有类似的代码:
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
运行时,例如 2,000 个条目,然后对于一些多处理运行,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'
的实验
可能会在错误输出中显示新字符串。
让我们考虑一下池的操作。
它序列化了 args
列表并发送了其中的一部分
给每个 child 进行反序列化和处理。
关于您的生产设置
比这里发布的漂亮的简单代码更复杂。
我不确定您的 val
是否都是数字。
想象它们是混合类型,甚至它们都是字符串。
如果序列化器/反序列化器没有正确往返 列出带有疯狂 unicode 字符串或其他的元素 数据类型,那么它有可能得到 不同步。我们有时会看到这样的效果 通过 CSV 文件格式往返数据帧, 转义换行符和定界符并不完全有效。 听起来有点牵强,但这是一个可行的理论。
此外,数据值大于 4 KiB 管道缓冲区大小 应该可以正常工作,但可能会暴露不寻常的同步时序 行为。
走得更远,也许有什么东西在赛跑 并设法从中吞下/丢弃字符 child 正在阅读的 pipe 。确认您的 生产代码没有任何代码试图 以那种方式互动。归结为更简单和 和更简单的测试用例,仍然比什么更复杂 您发布,直到症状不再出现。
这都是推测性的,但它指出了可以 探索以确认/拒绝可能的故障模式。
您似乎正在以正确的方式使用游泳池 -- 应该 可以将此类数据值发送到工作进程。 这是使用多处理模块的正常方式。
提前或延迟、之前或之后执行初始化
worker are spawned,是这个模块的一个典型问题。
你可能会 open()
,然后是 fork()
,然后文件就打开了
在 parent 和 child 。有时这有助于
懒惰地推迟这样的行动,直到 child 开始之后,
所以每个 child 都有自己的文件私有(private)连接。
行动项目:
与其序列化大量感兴趣的数据, 保留该数据并仅传递行 ID 或文件名 到 children ,他们用它来取回 自己的批量数据。做那个实验会 帮助您更好地了解故障模式和 触发它的每个环境的详细信息。
祝你好运!
关于python - 多处理池在某些运行中丢失变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74120026/