Python - 守护线程



在 Python 中,守护线程用于运行对程序操作不重要的后台任务。它们允许您在后台运行任务,而无需担心跟踪它们。

Python 提供两种类型的线程:非守护线程和守护线程。默认情况下,线程是非守护线程。本教程将结合相关的示例,详细解释 Python 编程中的守护线程。

守护线程概述

有时,需要在后台执行任务。一种特殊的线程用于后台任务,称为守护线程。换句话说,守护线程在后台执行任务。这些线程处理非关键任务,这些任务可能对应用程序有用,但如果它们失败或在操作中途被取消,也不会妨碍应用程序。

此外,守护线程无法控制其何时终止。一旦所有非守护线程完成,程序将终止,即使此时仍有守护线程正在运行。

守护线程与非守护线程的区别

守护线程 非守护线程
如果只有守护线程正在运行(或者没有线程正在运行),则进程将退出。 如果至少有一个非守护线程正在运行,则进程将不会退出。
守护线程用于后台任务。 非守护线程用于关键任务。
守护线程会被突然终止。 非守护线程会运行到完成。

守护线程可以执行以下任务:

  • 创建在后台存储日志信息的 文件。

  • 在后台执行网络抓取。

  • 自动将数据保存到后台的数据库中。

在 Python 中创建守护线程

要创建守护线程,需要将Thread构造函数的daemon属性设置为 True。

t1=threading.Thread(daemon=True)

默认情况下,daemon属性设置为 None,如果将其更改为非 None,则 daemon 将明确设置线程是否为守护线程。

示例

请查看以下示例,以创建守护线程并使用daemon属性检查线程是否为守护线程。

import threading 
from time import sleep

# function to be executed in a new thread
def run():
   # get the current thread
   thread = threading.current_thread()
   # is it a daemon thread?
   print(f'Daemon thread: {thread.daemon}')

# Create a new thread and set it as daemon
thread = threading.Thread(target=run, daemon=True)

# start the thread
thread.start()

print('Is Main Thread is Daemon thread:', threading.current_thread().daemon)

# Block for a short time to allow the daemon thread to run
sleep(0.5)

它将产生以下输出

Daemon thread: True
Is Main Thread is Daemon thread: False

如果在主线程中创建线程对象没有任何参数,则创建的线程将是非守护线程,因为主线程不是守护线程。因此,在主线程中创建的所有线程默认为非守护线程。但是,我们可以通过在启动线程之前(也就是在调用start()方法之前)使用Thread.daemon属性将daemon属性更改为True

示例

这是一个示例:

import threading 
from time import sleep

# function to be executed in a new thread
def run():
   # get the current thread
   thread = threading.current_thread()
   # is it a daemon thread?
   print(f'Daemon thread: {thread.daemon}')

# Create a new thread  
thread = threading.Thread(target=run)

# Using the daemon property set the thread as daemon before starting the thread
thread.daemon = True

# start the thread
thread.start()

print('Is Main Thread is Daemon thread:', threading.current_thread().daemon)

# Block for a short time to allow the daemon thread to run
sleep(0.5)

执行上述程序后,我们将得到以下输出:

Daemon thread: True
Is Main Thread is Daemon thread: False

管理守护线程属性

如果尝试在启动线程后设置其守护进程状态,则会引发RuntimeError。

示例

这是一个演示在尝试启动线程后设置其守护进程状态时如何引发RuntimeError 的另一个示例。

from time import sleep
from threading import current_thread
from threading import Thread

# function to be executed in a new thread
def run():
   # get the current thread
   thread = current_thread()
   # is it a daemon thread?
   print(f'Daemon thread: {thread.daemon}')
   thread.daemon = True
   
# create a new thread
thread = Thread(target=run)

# start the new thread
thread.start()

# block for a 0.5 sec for daemon thread to run
sleep(0.5)

它将产生以下输出

Daemon thread: False
Exception in thread Thread-1 (run):
Traceback (most recent call last):
   . . . .
   . . . .
    thread.daemon = True
  File "/usr/lib/python3.10/threading.py", line 1203, in daemon
    raise RuntimeError("cannot set daemon status of active thread")
RuntimeError: cannot set daemon status of active thread
广告