• Does Daemon Thread Exit with Main Thread?


    主线程(进程)退出后,主线程创建的守护线程也会退出吗?

    通过下面的代码测试:

    Demo1: 进程创建普通线程

    #!/usr/bin/python3
    # FileName: daemonThread.py
    # Author: lxw
    # Date: 2016-02-25
    
    import threading
    import time
    
    def show(num):
        time.sleep(3)
        print("In show(): {0}".format(num))
        with open("/home/lxw/Documents/NOTE", "w") as f:
            f.write("hello")
    
    def main():
        th = threading.Thread(target=show, args=(1,))
        #th.setDaemon(True)
        th.start()
        print("main() over. Program exit!")
    
    
    if __name__ == '__main__':
        main()
    else:
        print("Being imported as a module.")

    运行结果:

    lxw Documents$ python3 daemonThread.py 
    main() over. Program exit!
    In show(): 1
    lxw Documents$ 

    "The entire Python program exits when no alive non-daemon threads are left".

    只有当前进程的所有非守护线程 全部结束后,当前进程才能结束。

    Demo2: 进程创建守护线程

    #!/usr/bin/python3
    # FileName: daemonThread.py
    # Author: lxw
    # Date: 2016-02-25
    
    import threading
    import time
    
    def show(num):
        time.sleep(3)
        print("In show(): {0}".format(num))
        with open("/home/lxw/Documents/NOTE", "w") as f:
            f.write("hello")
    
    def main():
        th = threading.Thread(target=show, args=(1,))
        th.setDaemon(True)
        th.start()
        print("main() over. Program exit!")
    
    
    if __name__ == '__main__':
        main()
    else:
        print("Being imported as a module.")

    运行结果:

    lxw Documents$ ls
    daemonThread.py  NOTE  ThreadPool_Python
    lxw Documents$ rm NOTE 
    lxw Documents$ ls
    daemonThread.py  ThreadPool_Python
    lxw Documents$ python3 daemonThread.py 
    main() over. Program exit!
    lxw Documents$ ls
    daemonThread.py  ThreadPool_Python

    从运行结果我们可以看到,当前进程的守护线程 并没有结束,但当前进程仍然可以退出。并且当前进程结束后,该进程的守护线程也会结束,不会继续运行。

    也就是说进程退出并不考虑守护线程,只考虑非守护线程。

    通过这两段代码的验证,我们可以得出本文标题的答案:进程结束后,该进程的守护线程也会结束,不会继续运行。

    Reference:

    1. [Java基础] java的守护线程与非守护线程 虽然这篇文章讲的是Java的,但和Python也是通用的。
    守护线程并非虚拟机内部可以提供,用户也可以自行的设定守护线程,方法:public final void setDaemon(boolean on) ;但是有几点需要注意:
    1). thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个 IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。(备注:这点与守护进程有着明显的区别, 守护进程是创建后,让进程摆脱原会话的控制+让进程摆脱原进程组的控制+让进程摆脱原控制终端的控制;所以说寄托于虚拟机的语言机制跟系统级语言有着本质上面的区别)
    2). 在Daemon线程中产生的新线程也是Daemon的。(这一点又是有着本质的区别了:守护进程fork()出来的子进程不再是守护进程,尽管它把父进程的进程相关信息复制过去了,但是子进程的进程的父进程不是init进程,所谓的守护进程本质上说就是“父进程挂掉,init收养,然后 文件0,1,2都是/dev/null,当前目录到/”)

    2. 这篇博文的评论

  • 相关阅读:
    样式
    笔试:输入输出
    kafka hbase MR
    数据库
    Spring
    转:Numpy扩充矩阵维度(np.expand_dims, np.newaxis)和删除维度(np.squeeze)的方法
    PyTorch LSTM,batch_first=True对初始化h0和c0的影响
    矩阵F范数的平方转化为矩阵的迹
    Python自带的random库,numpy的随机库,torch的随机函数
    转:sklearn中的高斯混合模型GMM
  • 原文地址:https://www.cnblogs.com/lxw0109/p/daemon_thread.html
Copyright © 2020-2023  润新知