Python 守护程序线程未在 Windows 上退出

Posted

技术标签:

【中文标题】Python 守护程序线程未在 Windows 上退出【英文标题】:Python daemon threads are not exiting on Windows 【发布时间】:2019-08-12 19:47:32 【问题描述】:

我正在尝试理解 Python 中的守护线程。我的理解是,一旦主线程退出或非守护线程被杀死,守护线程就会自动被杀死。但是,在 Windows 机器上,这不是我的观察结果。

import threading
import time


def print_work_a():
    print('Starting of thread :', threading.currentThread().name)
    time.sleep(2)
    print('Finishing of thread :', threading.currentThread().name)


def print_work_b():
    print('Starting of thread :', threading.currentThread().name)
    print('Finishing of thread :', threading.currentThread().name)

a = threading.Thread(target=print_work_a, name='Thread-a', daemon=True)
b = threading.Thread(target=print_work_b, name='Thread-b')

a.start()
b.start()

观察到的输出:

>>> Starting of thread :Thread-a
Starting of thread :Thread-b


Finishing of thread :Thread-b

Finishing of thread :Thread-a

我预计输出不会包含 Finishing of thread :Thread-a,因为到那时非守护线程将被终止,因此守护线程也将被终止。导致守护线程保持活动的代码中的错误是什么?

【问题讨论】:

【参考方案1】:

来自docs:

可以将线程标记为“守护线程”。这件事的意义 flag 是当只有守护线程时整个 Python 程序退出 剩下的。

daemon 线程的问题是,例如,当从 shell(或 IDE)运行时,shell 本身 是主线程!因此,daemon 线程将与 shell 存在一样长,并将完成执行。我猜这就是你的情况。

尝试通过 cmd 运行您的脚本,您的预期输出将会出现。意思是,thread-a 不会完成。将您的代码复制到.py 文件后,我通过基本的python shell (IDLE) 运行它并得到:

>>> Starting of thread :Starting of thread :  Thread-aThread-b

Finishing of thread : Thread-b
Finishing of thread : Thread-a

但是,在运行cmd时,我得到了:

Starting of thread : Thread-a
Starting of thread : Thread-b
Finishing of thread : Thread-b

【讨论】:

【参考方案2】:

我不禁注意到您的输出中有一个>>>。您是否在交互式解释器中运行/导入它?如果是这样,交互式解释器仍将运行,因此daemon 线程有足够的时间退出,除非您在两秒内终止交互式解释器。您需要在常规 OS shell 中将其作为独立脚本运行(例如 Windows 上的 cmd.exe、类 UNIX 系统上的 bash 或类似系统等)。

【讨论】:

以上是关于Python 守护程序线程未在 Windows 上退出的主要内容,如果未能解决你的问题,请参考以下文章

剖析将自身分叉为守护进程的 python 程序

119 python程序中的线程操作-守护线程

Boost.Thread 线程在发布版本中未在 iPhone/iPad 上启动

Python线程:线程的调度-守护线程

java.lang.AssertionError:Cassandra守护程序未在超时内启动

python基础 多线程threading join 守护线程setDeamon 递归锁Rlock