父线程退出时,Python守护程序线程不会退出

时间:2014-02-18 03:45:19

标签: python multithreading daemon

我有一些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守护程序线程不会退出?

3 个答案:

答案 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的连接。

了解详情:http://docs.python.org/2/library/threading.html

答案 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进行测试