python 子进程进程在字典大小更改时崩溃

python subprocess Process crashes when dictionary size changes

NOTE:问题最终与subprocess无关,只是简单的dict修改在迭代时。

我有一个 class Agent,它有一个 launch() 方法来执行一系列操作 - 抓取数据、写入日志、打印到控制台。这个方法接受一个字典列表,其中有一堆参数控制它做什么,它循环遍历这个字典列表,为每个字典做类似的工作。 注:启动,launch()调用subprocess.Popen(一次)启动终端应用需要运行 launch() 执行其工作。

launch() 期间,每个字典都被修改了——例如,添加了一个用于跟踪已创建文件的键,添加了另一个键,其中包含 launch() 对该字典参数所做工作的统计信息等。当 launch() 遍历所有参数字典时,我返回并循环遍历字典,将每个字典保存到 pickle 文件中以备后用。

我的问题是我正在使用 subprocess.Process 并行启动多个 Agent 实例(每个实例都有自己的参数指令列表)。 注意: 每个调用其自己的 subprocess.Popen 并向其打开的终端应用程序调用不同的 cmdline args。一切正常,他们都创建了他们的日志(正确保存到文件),将他们的信息打印到控制台,获取他们正确的数据。但是,当每个人 launch() 的主循环完成并且他们尝试循环遍历各自的参数字典时,我为每个 Process 实例收到以下错误(包括完整的回溯以防它起源于何处) !):

Process Process-1:
Traceback (most recent call last):
  File "/Users/--/.pyenv/versions/2.7.10/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/Users/--/.pyenv/versions/2.7.10/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "../app/api.py", line 28, in spawn
    agent.launch(**kwargs)
  File "../app/agent.py", line 94, in launch
    self.subagent.launch(...)
  File "../app/subagent.py", line 445, in launch
    for param_dicts in self.finished+self.graveyard:
RuntimeError: dictionary changed size during iteration

如能深入了解发生这种情况的原因以及如何处理此错误的建议,我们将不胜感激!

错误消息准确说明了问题所在:

>>> d = {1: 2}
>>> for k in d:
...     d[3] = 2
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

要修复它,如果您必须在循环内修改字典(或者如果您有可能执行此操作的后台线程),请复制键:

>>> for k in list(d):
...     d[4] = 3
... 
>>>

在单独的进程中修改字典是可以的。默认情况下,进程处理数据的副本。