python 有两种类型线程
- 守护线程 (主程序退出,守护线程也会被kill)
- 其他线程(非守护线程)
举例: 生成两个线程, 其中一个运行更久的时间,
import threading
import time
def print_work_a():
print("starting of thread: ", threading.currentThread().name)
time.sleep(2)
print("starting of thread: ", threading.currentThread().name)
def print_work_b():
print('string of thread:', threading.currentThread().name)
print('string of thread:', threading.currentThread().name)
a = threading.Thread(target=print_work_a, name='Thread-a')
b = threading.Thread(target=print_work_b, name='Thread-b')
a.start()
b.start()
"""
(pythonparallel) D:\projects\pythoncode\pythonparallel>python pythreaddemo.py
starting of thread: Thread-a
string of thread: Thread-b
string of thread: Thread-b
starting of thread: Thread-a
(pythonparallel) D:\projects\pythoncode\pythonparallel>
"""
主线程、执行线程全部执行完毕后,才退出。
现在将 Thread-a作为守护进程。
# 程序修改的部分
a = threading.Thread(target=print_work_a, name='Thread-a', daemon=True)
b = threading.Thread(target=print_work_b, name='Thread-b')
"""
(pythonparallel) D:\projects\pythoncode\pythonparallel>python pythreaddemo.py
starting of thread: Thread-a
string of thread: Thread-b
string of thread: Thread-b
(pythonparallel) D:\projects\pythoncode\pythonparallel>
"""
主线程,与所有非守护进程全部执行完毕后,就退出了(没有等待 thread-a 守护进程执行完毕)
有些线程执行后台任务,例如发送keepalive数据包,或执行定期垃圾收集等等。这些仅在主程序运行时才有用,并且一旦其他非守护程序线程退出就可以将它们终止。
如果没有守护程序线程,您必须跟踪它们,并在程序完全退出之前告诉它们退出。通过将它们设置为守护程序线程,您可以让它们运行并忘记它们,当程序退出时,任何守护程序线程都会自动终止
daemon thread 和守护进程没什么卵关系
是的,他们主要的共同点就是都包含单词“daemon”。但非要说一点联系没有也是不对的。一般而言,被 flag 为 daemon 的线程需要长期在后台执行(比如发送心跳包、检查未读消息等),并且不需和用户直接交互,和守护进程类似。
总结
简单来说就是,本来并没有 daemon thread,为了简化程序员的工作,让他们不用去记录和管理那些后台线程,创造了一个 daemon thread 的概念。这个概念唯一的作用就是,当你把一个线程设置为 daemon,它会随主线程的退出而退出。关键点有三个:
- background task
- only useful when the main program is running
- ok to kill
参考
https://laike9m.com/blog/daemon-is-not-daemon-but-what-is-it,97/