注意: 问题最终与subprocess
没有任何关系,只是在迭代时进行了简单的字典修改。
我有一个类Agent
,它有launch()
方法执行一系列操作 - 抓取数据,写入日志,打印到控制台。这个方法采用一系列带有一系列参数的字典来控制它的作用,它循环遍历这个字典列表,为每个字典做类似的工作。 注意: 开始,launch()
调用subprocess.Popen
(一次)以启动需要为launch()
运行的终端应用程序执行其工作。
在launch()
期间,每个字典都会被修改 - 例如,添加了一个键用于跟踪已创建的文件,另一个键添加了launch()
在该字典上执行的工作的统计信息。当launch()
遍历所有参数dicts时,我返回并遍历dicts以将每个文件保存到pickle
文件以供日后使用。
我的问题是我使用Agent
并行启动了几个subprocess.Process
个实例(每个实例都有自己的参数序列列表)。 注意: 每个人都会调用自己的subprocess.Popen
,其中包含不同的cmdline args到它打开的终端应用。一切正常,他们都创建他们的日志(正确保存到文件),打印他们的信息到控制台,获取他们正确的数据。但是,当每个人launch()
的主循环结束并且他们试图遍历各自的参数dicts时,我会为每个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
对于为什么会发生这种情况以及如何处理此错误的建议,我们将非常感激!
答案 0 :(得分:3)
错误消息确切地说明问题所在:
>>> 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
...
>>>
在单独的过程中修改字典是可以的。默认情况下,进程处理数据副本。