我正在使用多处理来执行一系列串行任务。这些任务在位于不同文件夹中的不同文件上每次都相同。每个任务都由对其他几个模块和C ++程序的调用组成。有一个高级包装器来管理对其他模块/功能的调用。在执行多处理代码的开始,创建具有id和该高级类的实例的列表。然后,一个进程池执行任务。
它运行正常,直到出现模糊异常:
Traceback (most recent call last):
File "test_parallel.py", line 197, in <module>
pool_outputs = pool.map(do_calculations, zip(list_instances, list_IDs), )
File "/usr/lib64/python2.6/multiprocessing/pool.py", line 148, in map
return self.map_async(func, iterable, chunksize).get()
File "/usr/lib64/python2.6/multiprocessing/pool.py", line 422, in get
raise self._value
IndexError: tuple index out of range
当任务执行很多次时(通常在计划的200次上执行~100次任务),通常会。
缩短版的代码是:
import multiprocessing
if __name__=="__main__":
which_subfields=range(200)
pool_size = int( multiprocessing.cpu_count() )
run = WrapperAroundModule.run(version = "parallel")
if pool_size == 0:
pool_size=1
list_IDs = list(which_subfields)
lock=multiprocessing.Lock()
runs = []
for _ in which_subfields:
runs.append(copy.deepcopy(run))
pool = multiprocessing.Pool(processes=pool_size, )
pool_outputs = pool.map(do_calculations, zip(list_instances, list_IDs), )
pool.close()
pool.join()
do_calculations
函数的签名为:do_calculations((instance, id))
我确保函数do_calculations
是线程安全的,但它没有改变这种情况,然后我想使用maxtasksperchild
,但不幸的是我必须使用python 2.6和模块Billard无法安装在服务器上(运行scientific linux)我正在使用。因此,我写了一个解决方法:要执行的任务除以长度为pool_size*maxtasksperchild
的块。脚本使用类似的代码在池上执行这些任务。完成后,将删除池及其周围的所有变量,并使用下一个任务创建新池。可悲的是,错误在某些时候仍然存在。而且,我确保作为参数传递的两个列表足够长。函数do_calculations
可以在多处理版本中失败的单个任务上顺利运行。
对此错误的来源和可能的更正有任何想法吗?
答案 0 :(得分:5)
raise self._value
表示do_calculations
在子进程中引发了异常,multiprocessing
在主进程中为您重新引发了异常。
要解除异常,请修复do_calculations()
函数。用try/except
换行并打印完整的回溯/本地,以了解错误的位置。