python线程的daemon参数

2019年11月7日 / 21次阅读 / Last Modified 2019年12月28日
多线程

网上很难找到对python在创建线程时的daemon参数的说明,官方的说明并没有解释daemon到底是什么意思,有什么样的行为,下面是官方的解释。

python官方在Threading库中是这样描述daemon属性的:

daemon
A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

什么是daemon线程?

daemon线程具有这样的特性,即当创建它的程序终止后,daemon线程会自动终止运行。也有人说daemon线程时守护线程,守护这个词用得还不错,当守护对象已经关闭,这些线程也就没有存在的必要,会被自动杀掉。还有人称daemon线程为后台线程。

非daemon线程,正好反过来,创建它的程序终止后,非daemon线程不会自动终止运行。因此,有人称这位前台线程。前台线程会持续运行,直到它自己结束,或被kill。

因此,线程是否daemon,要看你的需求了。

如何设置daemon=True?

下面这段代码,创建两个daemon=True的线程,然后主线程执行完毕:

import time
import threading

def ppp():
    while True:
        print('i am in thread ppp')
        time.sleep(2)

def uuu():
    while True:
        print('i am in thread uuu')
        time.sleep(3)

t1 = threading.Thread(target=ppp, args=(), daemon=True)
t1.start()
t2 = threading.Thread(target=uuu, args=(), daemon=True)
t2.start()

两个daemon=True的线程,执行体都是死循环,我们来看看执行效果:

$ python3 thread.py
i am in thread ppp
i am in thread uuu

两行打印显示出来,程序就停止了,两个线程也停止了!因为daemon=True,是守护线程,是后台线程,因此主线程执行完毕后,这些线程就自动被停止了。

如果把刚才代码中,两个线程的参数修改为daemon=False,执行效果如下:

$ python3 thread.py
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread ppp
i am in thread uuu
i am in thread ppp
......

就停不下来了,只能Ctrl-C!

一个有趣的现象

以上已经把线程daemon的问题说清楚了,不过,我又做了一个测试,发现一个有趣的现场。如果把上文的代码,一个线程是daemon=True,另一个是daemon=False,会怎么样呢?代码如下:

import time
import threading

def ppp():
    while True:
        print('i am in thread ppp')
        time.sleep(2)

def uuu():
    while True:
        print('i am in thread uuu')
        time.sleep(3)

t1 = threading.Thread(target=ppp, args=(), daemon=True)
t1.start()
t2 = threading.Thread(target=uuu, args=(), daemon=False)
t2.start()

执行效果如下:

$ python3 thread.py
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread uuu
i am in thread ppp
i am in thread ppp
i am in thread uuu
......

两个线程都停不下来!!难道一个python程序里面,不能同时存在两个daemon设置不一样的线程?

RuntimeError

调试线程时,容易出现RuntimeError,很可能的原因,就是主线程退出后,效果资源已经被释放了,但是线程的退出滞后,或者线程daemon=False,这时线程如果要访问已经被主线程释放了的资源,就会出现这个异常。我之前在云上小悟分享过一篇,请参考:解决RuntimeError: main thread is not in main loop

-- EOF --

本文链接:https://www.pynote.net/archives/1477

留言区

《python线程的daemon参数》有4条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    python默认的线程机制(daemon=False),这样设计应该是考虑线程应该自己干完自己的事情,然后自己会退出。python线程没有直接kill机制,只有join去等待期结束。 [回复]

  • 麦新杰

    python中得thread的一些机制和C/C++不同:在C/C++中,主线程结束后,其子线程会默认被主线程kill掉。而在python中,主线程结束后,会默认等待子线程结束后,主线程才退出。 [回复]

  • 麦新杰

    进程是资源分配的最小单位,线程是CPU调度的最小单位.每一个进程中至少有一个线程。  [回复]

  • 麦新杰

    GUI程序,点一个按钮,然后执行一个动作,进行一些打印输出(比如在Text控件中),如果希望打印输出比较自然平滑流畅,执行动作的代码应该放入一个thread,在thread中进行打印输出。否则,打印输出总是在最后一刻,一口气出现在界面上。。。 [回复]


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top