在一个含有线程的python程序中,当主线程的代码运行完之后,如果还有其他子线程还未执行完毕,那么主线程会等待子线程执行完毕之后,再结束;如果有一个线程必须设置为无限循环,那么该线程不结束,意味着整个python程序就不能结束,那为了能够让python程序正常退出,将这类无限循环的线程设置为守护线程,当程序当中仅仅剩下守护线程时,python程序就能够正常退出,不必关心这类线程是否执行完毕,这就是守护线程的意义。
本篇从守护线程的创建、守护线程的继承、含有守护线程的程序退出与注意等介绍了python中的守护线程。一个线程(非守护线程)可以通过两种方式设置为守护线程:在创建完线程,启动线程之前,通过setDaemon(True)方法,将线程设置为守护线程
在利用Thread()构造线程时,将参数daemon设置为True,将线程设置为守护线程
必须在线程启动前(调用start())之前进行设置
def sub_thread():
print('hello world')
# 通过设置构造函数的参数daemon=True,将线程变为守护线程
t = threading.Thread(target=sub_thread, daemon=True)
# 通过属性.setDaemon=True,将线程变为守护线程
t.setDaemon(True)
# 必须在线程启动之前设置线程是否为守护线程
t.start()
2. 线程会继承当前线程的daemon的值,当前线程为守护线程,那么在该线程中新建的线程默认为守护线程:主线程是非守护线程,因此在主线程中新建线程默认都是非守护线程
在一个守护线程中,再创建新的线程时,就会继承当前线程的Daemon值,成为守护线程,例如:
def sub_thread():
def grandson():
print('i am a grandson thread')
t1 = threading.Thread(target=grandson)
t1.start()
t1.join()
print("the grandson's Daemon is %s " % t.isDaemon())
t = threading.Thread(target=sub_thread, daemon=True)
t.start()
t.join()
print("the parent's Daemon is %s" % t.isDaemon())
在主线程当中,通过设置daemon的参数为True,将sub_thread设置为守护线程,那么在sub_thread中创建的grandson线程,会继承sub_thread的Daemon的值,为守护线程。
3. 当一个python程序中,只剩下守护线程时,并不会等待守护线程执行完毕,Python程序就会退出,所以在守护线程中不适合执行一些操作,比如文件的写入等等:
def daemon_thread():
for i in range(5):
time.sleep(1)
print('in Daemon the number is %d' % i)
def sub_thread():
for i in range(5, 10):
print(' in non-daemon the number is %d' % i)
t = threading.Thread(target=daemon_thread, daemon=True)
t1 = threading.Thread(target=sub_thread, daemon=False)
t.start()
t1.start()
print('我结束了...')
其输出结果:
其中,子线程daemon_thread()中,打印的内容,并不能够全部输出,程序就结束退出了
4. 虽然当主线程结束时,守护线程也会跟着结束,但不意味着,守护线程不会输出任何东西,毕竟系统通知守护线程该结束了,也会需要一些时间,如:
def sub_thread():
print('hello world')
# 通过设置构造函数的参数daemon=True,将线程变为守护线程
t = threading.Thread(target=sub_thread, daemon=True)
t.start()
print('我结束了')
按理说,打印出“我结束了",意味着主线程结束了,不应该再打印出 "hello world",因为系统通知守护线程也需要时间,所以有可能会在我结束了,后面输出守护线程的内容,如果在守护线程中,添加一个耗时操作,守护线程1s中的睡眠时间,时间足够系统通知守护线程该结束了,所以结果仅仅输出主线程的结果:
参考:https://docs.python.org/3/library/threading.html?highlight=daemon#threading.Thread.daemondocs.python.org
水平有限,可能理解有误,欢迎批评指正与交流