我在程式中遇到了一個問題,即在啟動嵌套子行程后未引發例外。也就是說,我有一個在 multiprocessing.Process 中運行的方法。在該行程(“第一個行程”)內部,我啟動了另一個 multiprocessing.Process。在第二個行程呼叫 start 后,第一個行程繼續但不引發例外,而是在引發例外時掛起。
我無法判斷這是否是預期行為,或者我偶然發現了 Python 中的一個錯誤。這是一個演示該問題的最小示例:
import multiprocessing as mp
import time
def spin_proc():
while True:
print("spin")
time.sleep(1)
def issue():
sub_proc = mp.Process(target=spin_proc)
sub_proc.start()
print("Exception called next.") # This text is printed, as expected.
raise Exception() # This exception is never raised.
print("This text is not printed.")
first_proc = mp.Process(target=issue)
first_proc.start()
輸出是:
$ python3 except.py
Exception called next.
spin
spin
spin
spin
它會無限期地繼續列印“旋轉”,直到我按下 Ctrl-C。我本來預計會引發例外并使程式崩潰。
我已經在 Python 3.8.10 和 Python 3.9.2 中確認了這種行為。
Is this expected behavior? If so, why? It has the effect of hiding exceptions in my code and unexpectedly blocking, which was very frustrating when trying to debug something new and not seeing any output. If it appears to be a bug, please let me know and I will report it to the Python bug tracker.
Thank you! And here is the output when pressing Ctrl-C. It seems it wanted to throw the Exception, but was hanging for some reason:
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 27, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
Process Process-1:1:
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "except.py", line 7, in spin_proc
time.sleep(1)
KeyboardInterrupt
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "except.py", line 13, in issue
raise Exception() # This exception is never raised.
Exception
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 318, in _bootstrap
util._exit_function()
File "/usr/lib/python3.8/multiprocessing/util.py", line 357, in _exit_function
p.join()
File "/usr/lib/python3.8/multiprocessing/process.py", line 149, in join
res = self._popen.wait(timeout)
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 47, in wait
return self.poll(os.WNOHANG if timeout == 0.0 else 0)
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 27, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
uj5u.com熱心網友回復:
好的,這似乎是我的用戶錯誤。我在 Twitter 上發布了這個問題,用戶 @strinkleydimbu1 指出我可以使用 daemon 標志產生預期的行為。具體來說,您可以更改此行:
sub_proc = mp.Process(target=spin_proc)
到
sub_proc = mp.Process(target=spin_proc, daemon=True)
程式按預期運行。守護行程標志告訴python如果父母死了就殺死所有的孩子。沒有這個,它必須無限期地等待孩子完成。令我驚訝的是,例外會掛起而不是做任何事情,但由于我沒有徹底閱讀檔案,我不能說這種行為是否真的出乎意料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/437709.html
