classification
Title: No reliable clean shutdown method
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Void2258, josh.r
Priority: normal Keywords:

Created on 2018-03-16 17:44 by Void2258, last changed 2018-03-20 00:19 by brett.cannon.

Messages (2)
msg313961 - (view) Author: Elliot Jenner (Void2258) Date: 2018-03-16 17:44
Ptyhon lacks a reliable clean shutdown method. sys.exit(), which should be this method, does not reliably perform this function as it merely terminates the thread it is called from (duplicating the functionality of thread.exit()), exit() and quit() are not supposed to be used except in terminal windows, raise SystemExit has the same issues as sys.exit() and is bad practice, and os._exit() immediately kills everything and does not clean up, which can cause issues with residuals.

This is especially important as some interpreters will break calls (including most worryingly try-except clauses) into threads invisibly, leading to whichever method is used being called in a non-main thread without anything the programmer can do about it even when you are not intentionally using threading.

Ideally, sys.exit() should be changed to properly close down the entire program, as there is no need for 2 functionally identical exit functions, but this may cause legacy issues. Regardless, a method that ALWAYS kill the program and all threads while still cleaning up, regardless of where it is called from, is needed.
msg313969 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2018-03-16 19:38
To my knowledge, there is no safe way to do this for other threads for a reason.

If you make all your worker threads daemons, then they will terminate with the main thread, but they won't perform cleanup actions.

If you don't make them daemons, any "clean exit" procedure risks the threads choosing not to exit (even if you inject a SystemExit into every other thread, they might be in a try/except: or try/finally that suppresses it, or blocks waiting for something from another thread that has already exited, etc.). Exiting the thread that calls sys.exit() this way is considered okay, since you control when it is called, and it's up to you to do it at a safe place, but doing so asynchronously in other threads introduces all sorts of problems.

Basically, you want a reliable "shut down the process" and a reliable "clean up every thread", but anything that allows clean up in arbitrary threads also allows them to block your desired "shut down the process". Do you have a proposal for handling this?
History
Date User Action Args
2018-03-20 00:19:56brett.cannonsettype: behavior -> enhancement
versions: + Python 3.8, - Python 2.7, Python 3.4, Python 3.5, Python 3.6, Python 3.7
2018-03-16 19:38:27josh.rsetnosy: + josh.r
messages: + msg313969
2018-03-16 17:44:07Void2258create