当父线程退出时,Python守护进程线程不退出

2024-04-26 07:35:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些创建恶魔线程的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()

系统版本:

'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守护进程线程不退出?


Tags: importtargettime进程maindefsleep线程
3条回答

完整性请看这篇文章。 https://joeshaw.org/2009/02/24/605/

The monitoring was done inside a daemon thread. The Python docs say only:

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.

Which sounds pretty good, right? This thread is just occasionally grabbing some data, and we don’t need to do anything special when the program shuts down. Yeah, I remember when I used to believe in things too.

Despite a global interpreter lock that prevents Python from being truly concurrent anyway, there is a very real possibility that the daemon threads can still execute after the Python runtime has started its own tear-down process. One step of this process appears to be to set the values inside globals() to None, meaning that any module resolution results in an AttributeError attempting to dereference NoneType. Other variations on this cause TypeError to be thrown.

我不确定这是一个已经被修复的bug,还是一个仍然存在的bug,或者按照设计的行为。但如果你觉得奇怪,就把这个放在脑后。

因此,另一种方法是在exit标志的子线程中循环,完成后可以在main中设置该标志。然后在主管道中等待子线程死亡,然后清理。

我只能在python shell中重现OP(无休止的“sleep”输出)所描述的行为。如果从一个文件运行,它将按预期工作(几行'sleep'和一行'main thread end…')

类似地,如果作为文件运行,第二个程序会立即退出,但在从python shell运行时,也会打印出无休止的“sleep”语句。

我的结论是:由于作为python shell的线程即使在“main”完成之后仍然继续运行,因此当从pythonshell运行时,守护进程不会被终止。

这是否可以被认为是一个bug(即Python的行为取决于脚本的运行方式)或者是预期的?我听从更有经验的Python。。。

BTW-使用Python3.2.3测试

如果为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

相关问题 更多 >