-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Description
Bug report
It seems to me that threads running when sys.exit() is called during signal handling are killed immediately. It further seems that the try ... finally contract is adhered to on the main thread but broken in other threads.
Consider the following pice of Python code:
import signal
import sys
import time
from threading import Thread
def termination_signal_handler(_, __):
print("termination_signal_handler")
sys.exit()
def f():
try:
print("Begin f")
time.sleep(1000)
except SystemExit:
print("Got SystemExit in f")
raise
finally:
print("End f")
signal.signal(signal.Signals.SIGINT, termination_signal_handler)
signal.signal(signal.Signals.SIGTERM, termination_signal_handler)
try:
t = Thread(target=f, daemon=False)
t.start()
t.join()
except SystemExit:
print("Got SystemExit in main")
raise
finally:
print("End main")When running this code and hitting CTRL-C after a short while I get the following output:
$ python testthread.py
Begin f
^Ctermination_signal_handler
Got SystemExit in main
End main
The output indicates that the thread t was killed right away, leaving the finally (and the except SystemExit clause in f) unexecuted.
My expectation would have been that either (XOR)
- (a)
SystemExitwould be propagated to all threads - (b)
SystemExitraised on the main thread and the other threads are left running - (c) Nothing happens
According to the Python doc, non daemonic threads should not be killed when the main thread exits. Also, according to several SO posts, the expected behavior would more be in the area of (b).
Note: The same code without the signal handling is behaving in a similar way. The only difference there is that the KeyboardInterupt trace is also logged to the console.
Am I missing something?
Your environment
- CPython versions tested on: 3.11.4
- Operating system and architecture:
macOS-13.4.1-arm64-arm-64bit