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
...
>>>
在单独的进程中修改字典是可以的。默认情况下,进程处理数据的副本。
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
...
>>>
在单独的进程中修改字典是可以的。默认情况下,进程处理数据的副本。