Python/Java – 所谓的daemon守护线程
根据我多年C/C++研发经验,我从未听说过操作系统的线程有什么守护不守护之分,为什么Python和Java里面的Thread就有这么个选项呢?具体有什么区别呢?
看图说话
主线程明明已经打印了,为啥还在运行呢?
这是因为python threading这个库实现了一个应用层的线程行为,就是它有一个daemon属性。
daemon默认为False,这种情况下python解释器退出前会帮我们join回收线程,因为我们的线程是死循环,所以join不可能返回,导致主线程卡在join上退不掉。
注意,daemon是应用层库行为+python解释器行为,不是操作系统行为!
如果不想让python多管闲事,只需要做这样的修改即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import threading class MyThread(threading.Thread): def __init__(self): super(MyThread, self).__init__() def run(self) -> None: while True: pass t = MyThread() t.daemon = True t.start() print('退不掉') |
我遇到的场景
我是用python tkinter写GUI,在程序里我启动了线程,然后点击GUI的❌的时候,我发现虽然界面没了但是任务管理器里进程还活着,匪夷所思。
最终定位就是因为我的线程不是daemon的,所以点击❌后tkinter做了退出清理关闭界面了,但是代码真正退出前被join卡住了,所以导致了这个情况,因此只需要把自己创建的线程daemon=True即可。
为什么没踩过这个坑?
因为平时我们写python程序都是命令行执行,大多是kill信号杀死主线程,因此主线程不是优雅退出的,也就不会join。
而我这次写的tkinter程序点击❌之后是优雅退出main线程的,所以走入了线程join逻辑。
希望对大家有帮助。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~

1
1