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

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()返回之后这个线程仍“活着”。
运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43193719/article/details/89577071