當python腳本打開子進程和一個進程崩潰時會發生什麼?Python多處理:子進程中崩潰?
https://stackoverflow.com/a/18216437/311901
將會在主進程崩潰?
其他子流程會崩潰嗎?
是否存在傳播的信號或其他事件?
當python腳本打開子進程和一個進程崩潰時會發生什麼?Python多處理:子進程中崩潰?
https://stackoverflow.com/a/18216437/311901
將會在主進程崩潰?
其他子流程會崩潰嗎?
是否存在傳播的信號或其他事件?
當使用multiprocessing.Pool
,如果池中崩潰的子進程的一個,你會不會在所有的通知,和一個新的進程將立即啓動,以取代其位置:
>>> import multiprocessing
>>> p = multiprocessing.Pool()
>>> p._processes
4
>>> p._pool
[<Process(PoolWorker-1, started daemon)>, <Process(PoolWorker-2, started daemon)>, <Process(PoolWorker-3, started daemon)>, <Process(PoolWorker-4, started daemon)>]
>>> [proc.pid for proc in p._pool]
[30760, 30761, 30762, 30763]
然後在另一個窗口:
[email protected]:~$ kill 30763
回到池:
>>> [proc.pid for proc in p._pool]
[30760, 30761, 30762, 30767] # New pid for the last process
你可以像沒有任何事情一樣繼續使用池。但是,死亡子進程在其死亡時正在運行的任何工作項目將不會完成或重新啓動,而是而不是。如果您正在運行依靠該工作項目完成的阻止map
或apply
調用,該調用可能會無限期地掛起。有一個bug filed for this,但該問題僅在concurrent.futures.ProcessPoolExecutor
中修正,而不是在multiprocessing.Pool
中修復。從Python 3.3開始,如果子進程被終止,ProcessPoolExecutor
將引發BrokenProcessPool
異常,並且不允許進一步使用該池。可悲的是,multiprocessing
沒有得到這個增強。現在,如果您想防止由於子進程崩潰而導致永久性阻止池呼叫,則必須使用ugly workarounds。
注意:以上僅適用於處理池中實際上崩潰,這意味着該過程完全死亡。如果一個子進程拋出一個異常,當您嘗試檢索工作項目的結果將被向上傳播的父進程:
>>> def f(): raise Exception("Oh no")
...
>>> pool = multiprocessing.Pool()
>>> result = pool.apply_async(f)
>>> result.get()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/multiprocessing/pool.py", line 528, in get
raise self._value
Exception: Oh no
當使用multiprocessing.Process
直接,進程對象將顯示該進程已與一個非零退出代碼退出如果它崩潰:
>>> def f(): time.sleep(30)
...
>>> p = multiprocessing.Process(target=f)
>>> p.start()
>>> p.join() # Kill the process while this is blocking, and join immediately ends
>>> p.exitcode
-15
如果有異常的上升的行爲是類似的:
from multiprocessing import Process
def f(x):
raise Exception("Oh no")
if __name__ == '__main__':
p = Process(target=f)
p.start()
p.join()
print(p.exitcode)
print("done")
輸出:
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python3.2/multiprocessing/process.py", line 267, in _bootstrap
self.run()
File "/usr/lib/python3.2/multiprocessing/process.py", line 116, in run
self._target(*self._args, **self._kwargs)
TypeError: f() takes exactly 1 argument (0 given)
1
done
正如你所看到的,從孩子回溯印,但它不會影響主進程,這是能夠證明孩子的exitcode
的exceution是1
。