使用多处理池运行时,我发现工作进程一直在超出抛出异常的位置运行。
请考虑以下代码:
import multiprocessing
def worker(x):
print("input: " + x)
y = x + "_output"
raise Exception("foobar")
print("output: " + y)
return(y)
def main():
data = [str(x) for x in range(4)]
pool = multiprocessing.Pool(1)
chunksize = 1
results = pool.map(worker, data, chunksize)
pool.close()
pool.join()
print("Printing results:")
print(results)
if __name__ == "__main__":
main()
输出结果为:
$ python multiprocessing_fail.py
input: 0
input: 1
input: 2
Traceback (most recent call last):
input: 3
File "multiprocessing_fail.py", line 25, in <module>
main()
File "multiprocessing_fail.py", line 16, in main
results = pool.map(worker, data, 1)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
raise self._value
Exception: foobar
正如您所看到的,工作进程永远不会超过raise Exception("foobar")
到第二个打印语句。但是,它会一次又一次地在函数worker()的开头恢复工作。
我在文档中寻找了解释,但找不到任何解释。这是一个可能相关的SO问题:
Keyboard Interrupts with python's multiprocessing Pool
但这是不同的(关于键盘中断没有被主进程选中)。
另一个问题:
How to catch exceptions in workers in Multiprocessing
这个问题也有所不同,因为在它中主进程没有捕获任何异常,而在这里master确实捕获了异常(第16行)。更重要的是,在那个问题中,工作者没有超过异常(工作者只有一个可执行行)。
正在运行python 2.7
答案 0 :(得分:0)
评论:池应该启动一个worker,因为代码有pool = multiprocessing.Pool(1)。
来自Documnentation:
一个进程池对象,它控制可以提交作业的工作进程池
评论:一名员工多次运行worker()函数
来自文档:
map(func, iterable[, chunksize])
此方法将可迭代变为多个块,并将其作为单独的任务提交给流程池。
您的worker()
是单独的任务。将worker()
重命名为task()
有助于澄清什么是。
评论:我期望工作进程在异常处崩溃
确实,单独的任务,您的worker()
死亡,Pool
开始下一个任务。
您想要的是Pool.terminate()
来自文档:
terminate()
立即停止工作流程而不完成未完成的工作。
问题:...我发现工作进程一直在超出抛出异常的点。
您将iteration data
提交给Pool
,因此Pool
执行以下操作:
启动len(数据)工作人员。
data = [str(x) for x in range(4)]
主要问题是:您希望用什么
raise Exception("foobar")