Does Daemon Thread Exit with Main Thread?

发布于 2019-09-26 作者 风铃 5次 浏览 版块 前端

    <h1 class=\"postTitle\">
        <a id=\"cb_post_title_url\" class=\"postTitle2\" href=\"http://www.cnblogs.com/lxw0109/p/daemon_thread.html\">Does Daemon Thread Exit with Main Thread?</a>
    </h1>
    <div class=\"clear\"></div>
    <div class=\"postBody\">
        <div id=\"cnblogs_post_body\"><p>主线程(进程)退出后,主线程创建的守护线程也会退出吗?</p>

通过下面的代码测试:


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. 这篇博文的评论










    </div>
    <div class=\"postDesc\">posted @ <span id=\"post-date\">2016-02-25 00:28</span> <a href=\"http://www.cnblogs.com/lxw0109/\">lxw0109</a> 阅读(<span id=\"post_view_count\">...</span>) 评论(<span id=\"post_comment_count\">...</span>)  <a href=\"http://i.cnblogs.com/EditPosts.aspx?postid=5215601\" rel=\"nofollow\">编辑</a> <a href=\"#\" onclick=\"AddToWz(5215601);return false;\">收藏</a></div>
收藏
暂无回复