What does sys.exit really do with multiple threads?

谁都会走 提交于 2019-12-17 07:47:55

问题


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?


回答1:


As per the documentation sys.exit() raises SystemExit:

Exit the interpreter by raising SystemExit(status).

If SystemExit reaches the default exception handler, it calls handle_system_exit(), which more or less pushes through to Py_Finalize(), which in turn calls wait_for_thread_shutdown() in Python 2, so sys.exit() is the same as the normal falling off the bottom of the main module in waiting for all non-daemon threads to terminate.




回答2:


(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 (in other words, 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 isn't necessary since it's at the end of the script anyway).


A daemon thread is a low priority thread that runs in 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.




回答3:


In your case, the end of the program is when the last thread will be terminated. Maybe kind of join() method(like in Java) in python will wait for other threads.

Please, read this article(: there is a good explanation how to play with threads in your case Use of threading.Thread.join()

and

documentation https://docs.python.org/2/library/threading.html (but relax, it is only for additional knowledge.

and read this article about daemon property(if you do not want to wait for others threads become terminated Meaning of daemon property on Python Threads



来源:https://stackoverflow.com/questions/38804988/what-does-sys-exit-really-do-with-multiple-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!