Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does sys.exit really do with multiple threads?

I was really confused by sys.exit() in python. In python documentation, it says "Exit from Python"; does that mean when sys.exit() is called in a python program, the process will exit? If so, the code below shows a different result:

import sys
import time
import threading

def threadrun():
    while(True):
        time.sleep(1)

if __name__=="__main__":
    t=threading.Thread(target=threadrun)
    t.start()
    sys.exit()

Launching this program in linux, result was not the expected one as python documentation says but still run in the system, so what does sys.exit() really do?

like image 837
wdy Avatar asked Aug 06 '16 13:08

wdy


People also ask

What is the purpose of the sys exit () function?

exit() function allows the developer to exit from Python. The exit function takes an optional argument, typically an integer, that gives an exit status. Zero is considered a “successful termination”.

What happens to threads when main exits?

Exiting the main thread will not result in the process exiting if there are any other threads still active. According to the old-fashioned model of how processes exit, a process was in control of all its threads and could mediate the shutdown of those threads, thereby controlling the shutdown of the process.

Is SYS exit necessary?

There is no need to use sys. exit(0) at the end of your script if no problems have been found, and it is not good practice to do so. to get a different returncode.

How does Python handle SYS exit?

exit() is considered good to be used in production code for the sys module is always available. The optional argument arg can be an integer giving the exit or another type of object. If it is an integer, zero is considered “successful termination”. Note: A string can also be passed to the sys.


1 Answers

(Paraphrasing what's in the Python 2 documentation for Thread Objects)

Normally a Python program exits only when there's nothing but daemon threads (ignoring itself) left running. The “main thread” object which corresponds to the initial thread of control in the program isn't a daemon thread. Threads created using threading.Thread inherit their daemonic status from the creating thread, so if that's the main thread, they will also be non-daemonic.

This means that by default any threads created and started by your main program will prevent it from exiting if they are still running when the main thread is terminated (by sys.exit() or simply by just hitting the end of its code). In other words, the program exits only when no alive non‑daemon threads (i.e. only daemon threads) are left.

You can override this default behavior by explicitly setting✶✶ the daemon property of any created thread objects to True before starting it.

if __name__=="__main__":
    t = threading.Thread(target=threadrun)
    t.daemon = True  # Explicitly set property.
    t.start()
    sys.exit()

Which will allow the program to actually end when sys.exit() is called (although calling it explicitly like that would not be necessary since presumably the code above would be at the end of the script anyway).


A daemon thread is one that runs in the background and does not prevent the interpreter from exiting. See Daemon Threads Explanation.

✶✶ In Python 3.3, a daemon keyword argument with a default value of None was added to the Thread class constructor which means that, starting from that version onwards, you can simply use:

    # Sets whether the thread is daemonic via "daemon" keyword argument.
    t = threading.Thread(target=threadrun, daemon=True)

However, doing it separately via an explicit attribute assignment statement still works, and would therefore be the more version-portable way of doing it.

like image 57
martineau Avatar answered Sep 28 '22 02:09

martineau