Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Exiting <em>due</em> to a signal is not the same as exiting from <em>within</em> a signal handler. Catching a signal and exiting with sys.exit is a clean exit, not an exit due to a signal handler. So, yes, I agree that it should run atexit handlers here--at least in principle.</p> <p>However, there's something tricky about signal handlers: they're completely asynchronous. They can interrupt the program flow at any time, between any VM opcode. Take this code, for example. (Treat this as the same form as your code above; I've omitted code for brevity.)</p> <pre><code>import threading lock = threading.Lock() def test_loop(): while not terminate: print('looping') with lock: print "Executing synchronized operation" time.sleep(1) print('stopping thread') def run(): while True: time.sleep(2) with lock: print "Executing another synchronized operation" print('main') </code></pre> <p>There's a serious problem here: a signal (eg. ^C) may be received while run() is holding <code>lock</code>. If that happens, your signal handler will be run with the lock still held. It'll then wait for test_loop to exit, and if that thread is waiting for the lock, you'll deadlock.</p> <p>This is a whole category of problems, and it's why a <em>lot</em> of APIs say not to call them from within signal handlers. Instead, you should set a flag to tell the main thread to shut down at an appropriate time.</p> <pre><code>do_shutdown = False def close_handler(signum, frame): global do_shutdown do_shutdown = True print('caught signal') def run(): while not do_shutdown: ... </code></pre> <p>My preference is to avoid exiting the program with sys.exit entirely and to explicitly do cleanup at the main exit point (eg. the end of run()), but you can use atexit here if you want.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload