Python多处理不会因基本异常而终止
当使用多处理池运行时,我发现工作进程一直运行到抛出异常的点之后 考虑以下代码:Python多处理不会因基本异常而终止,python,exception-handling,python-multiprocessing,Python,Exception Handling,Python Multiprocessing,当使用多处理池运行时,我发现工作进程一直运行到抛出异常的点之后 考虑以下代码: 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)]
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
$python多处理\u fail.py
输入:0
输入:1
投入:2
回溯(最近一次呼叫最后一次):
投入:3
文件“multiprocessing_fail.py”,第25行,在
main()
文件“multiprocessing_fail.py”,第16行,主
结果=pool.map(工作者,数据,1)
文件“/usr/lib/python2.7/multiprocessing/pool.py”,第251行,在地图中
返回self.map\u async(func,iterable,chunksize).get()
get中的文件“/usr/lib/python2.7/multiprocessing/pool.py”,第558行
提升自我价值
例外:foobar
如您所见,辅助进程从未超出第二个print语句的raiseexception(“foobar”)
。但是,它会在函数worker()的开头一次又一次地恢复工作
我在文档中查找解释,但找不到任何解释。以下是一个可能相关的SO问题:
但这是不同的(关于主进程没有拾取键盘中断)
另一个问题:
这个问题也不同,因为在这里主进程不捕获任何异常,而在这里主进程捕获异常(第16行)。更重要的是,在这个问题中,worker没有运行过异常(worker只有一个可执行行)
我正在运行Python2.7
注释:池应该启动一个工作进程,因为代码具有Pool=multiprocessing.Pool(1) 来自文档:
一个进程池对象,它控制作业可以提交到的工作进程池
注释:一个工作者正在多次运行worker()函数 来自文档:
map(func,iterable[,chunksize])
此方法将iterable拆分为若干块,并将其作为独立任务提交给进程池
data = [str(x) for x in range(4)]
您的worker()
是单独的任务。将您的worker()
重命名为task()
有助于澄清问题
注释:我希望工作进程在异常时崩溃
确实如此,单独的任务,您的工作者()
死亡,池
开始下一个任务
您需要的是Pool.terminate()
来自文档:
terminate()
立即停止工作进程而不完成未完成的工作
问题:。。。我发现工作进程一直运行到抛出异常的点之后 您将
迭代数据
交给池
,因此池
执行它必须执行的操作:启动len(数据)工作线程
data = [str(x) for x in range(4)]
主要问题是:你希望从中得到什么
raise Exception("foobar")
@jordanm的可能副本感谢您的快速响应!我读了那个问题,发现它和我的不同。编辑以显示差异。它似乎没有运行,但通过了异常。字符串“output:”从不打印。在异常被抛出并消失后,它似乎只是产生了一个新的工作进程。如果您希望整个脚本在子进程中出现异常后消失,则需要检测它并退出主进程。@jordanm我让工作进程打印其id(使用multiprocessing.current_process())并且它打印相同的辅助进程id。它是经过异常的同一个辅助进程。池应该启动一个辅助进程,因为代码具有
Pool=multiprocessing.Pool(1)
。一个worker正在多次运行worker()函数(并且多次命中异常)。我所期望的是工作进程在异常时崩溃,因为它是一个未处理的异常。不幸的是,文档中没有提到这种情况。注释:池应该启动一个worker,因为代码具有Pool=multiprocessing.Pool(1)。从文档中:一个进程池对象,它控制作业可以提交到的工作进程池。
从文档中的下一行:进程是要使用的工作进程数。
和调用:类多处理.pool([processs[,initializer[,initargs[,maxstasksperchild]]]]
。因此应该只启动一个workercomment:它确实启动了,单独的任务,您的worker()死亡,而池启动下一个任务。函数worker()是一个函数对象,不能死亡。进程可以死亡。事实上,worker进程(如您所指出的,与worker()函数不同)不死是这里的主要问题。