第十章:使用进程、线程和协程提供并发性-threading:进程中管理并发操作-守护与非守护线程

本文深入探讨了守护线程在Python中的应用,解释了如何通过设置daemon属性来创建守护线程,以及如何使用join()方法来等待守护线程的完成。通过示例代码展示了守护线程与非守护线程的区别。

10.3.3 守护与非守护线程
到目前为止,示例程序都在隐式地等待所有线程完成工作之后才退出。不过,程序有时会创建一个线程作为守护线程(daemon),这个线程可以一直运行而不阻塞主程序退出。如果一个服务不能很容易地中断线程,或者即使让线程工作到一半时中止也不会造成数据损失或破坏(例如,为一个服务监控工具生成“心跳”的线程),那么对于这些服务,使用守护线程就很有用。要标志一个线程为守护线程,构造线程时便要传入daemon=True或者要调用它的setDaemon()方法并提供参数True。默认情况下线程不作为守护线程。

import threading
import time
import logging

def daemon():
    logging.debug('Starting')
    time.sleep(0.2)
    logging.debug('Exiting')

def non_daemon():
    logging.debug('Starting')
    logging.debug('Exiting')

logging.basicConfig(
    level=logging.DEBUG,
    format='(%(threadName)-10s) %(message)s',
    )

d = threading.Thread(name='daemon',target=daemon,daemon=True)

t = threading.Thread(name='non-daemon',target=non_daemon)
d.start()
t.start()

这个代码的输出中不包含守护线程的“Exiting”消息,因为在从sleep()调用唤醒守护线程之前,所有非守护线程(包活主线程)已经退出。
运行结果:
在这里插入图片描述
要等待一个守护线程完成工作,需要使用join()方法。

import threading
import time
import logging

def daemon():
    logging.debug('Starting')
    time.sleep(0.2)
    logging.debug('Exiting')

def non_daemon():
    logging.debug('Starting')
    logging.debug('Exiting')

logging.basicConfig(
    level=logging.DEBUG,
    format='(%(threadName)-10s) %(message)s',
    )

d = threading.Thread(name='daemon',target=daemon,daemon=True)

t = threading.Thread(name='non_daemon',target=non_daemon)

d.start()
t.start()

d.join()
t.join()

使用join()等待守护线程退出意味着他有机会生成它的“Exiting”消息。
运行结果:
在这里插入图片描述
默认地,join()会无限阻塞,或者,还可以传入一个浮点值,表示等待线程在多长时间 (秒数)后变为不活动。即使线程在这个时间段内未完成,join()也会返回。

import threading
import time
import logging

def daemon():
    logging.debug('Starting')
    time.sleep(0.2)
    logging.debug('Exiting')

def non_daemon():
    logging.debug('Starting')
    logging.debug('Exiting')

logging.basicConfig(
    level=logging.DEBUG,
    format='(%(threadName)-10s) %(message)s',
    )

d = threading.Thread(name='daemon',target=daemon,daemon=True)

t = threading.Thread(name='non-daemon',target=non_daemon)

d.start()
t.start()

d.join(0.1)
print('d.isAlive()',d.isAlive())
t.join()

由于传入的超时时间小于守护线程睡眠的时间,所以join()返回之后这个线程仍“活着”。
运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值