我有一些Python代码可以创建恶魔线程。父线程几乎立即结束,但守护程序线程保持打印睡眠状态。
import threading
import time
def int_sleep():
for _ in range(1, 600):
time.sleep(1)
print("sleep")
def main():
thread = threading.Thread(target=int_sleep)
thread.daemon = True
thread.start()
time.sleep(2)
print("main thread end...")
thread = threading.Thread(target=main)
thread.start()
内容sys.version:
'3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:19:30) [MSC v.1600 64 bit (AMD64)]'
打印:
sleep
main thread end...
sleep
sleep
sleep
为什么在父线程退出时,Python守护程序线程不会退出?
答案 0 :(得分:7)
如果为python线程指定thread.daemon = True
,那么只剩下守护进程时程序将立即停止。发送到stdout的命令丢失了。
将其添加到名为main.py
的文件中import threading
import time
def int_sleep():
for _ in range(1, 600):
time.sleep(1)
print("sleep")
def main():
thread = threading.Thread(target=int_sleep)
thread.daemon = True
thread.start()
time.sleep(2)
print("main thread end...")
thread = threading.Thread(target=main)
thread.daemon = True
thread.start()
像这样运行:
el@apollo:~/code/python/run01$ python --version
Python 2.7.6
el@apollo:~$ python main.py
el@apollo:~$
看到它打印没有,因为线程已启动。您将其设置为守护程序并启动它。然后程序结束了。
额外注意事项:如果将此代码粘贴到python解释器中,则所有print语句都将显示在终端上,因为守护程序永远不会失去与stdout的连接。
答案 1 :(得分:3)
为了完整性,请查看本文。 https://joeshaw.org/2009/02/24/605/
监视是在守护程序线程内完成的。 Python文档说 只有:
A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left.
听起来不错,对吧?偶尔这个帖子 抓住一些数据,我们不需要做任何特别的事情 程序关闭。是的,我记得我曾经相信的事情 太
尽管全局解释器锁定阻止了Python 无论如何真正并发,有一个非常现实的可能性 守护进程线程仍然可以在Python运行时启动后执行 它自己的拆卸过程。这个过程的一个步骤似乎是 将globals()内的值设置为None,表示任何模块 解决方案导致AttributeError尝试取消引用 NoneType。其他变体会导致抛出TypeError。
我不确定这是一个已修复的错误,还是一个仍然存在的错误或根据设计的行为。但是,如果你看到怪异,那就把它放在脑后。
所以另一种方法是在退出标志上循环子线程,当你完成时可以在主标志中设置。然后在主要处等待子线程死亡,然后清理。
答案 2 :(得分:1)
我只能重现OP描述的行为('sleep'的无限输出)如果从python shell完成。如果从文件运行它按预期工作(几行“睡眠”和一行“主线程结束......”)
同样,如果作为文件运行,第二个程序会立即退出,但是当从python shell运行时,它还会打印无休止的'sleep'语句。
我的结论:因为即使在“main”完成之后,作为python shell的线程仍继续运行,因此防止守护进程在从python shell运行时被终止。
这可能被视为一个错误(即Python的行为根据脚本的运行方式而有所不同)或是否是预期的?我推荐更有经验的Pythonistas ......
BTW - 使用Python 3.2.3进行测试