Python - Daemon Threads

Các luồng daemon trong Python rất hữu ích cho việc chạy các tác vụ nền không quan trọng đối với hoạt động của chương trình. Chúng cho phép bạn thực hiện các tác vụ trong nền mà không cần lo lắng về việc theo dõi chúng.

Python cung cấp hai loại luồng: luồng không daemon và luồng daemon. Theo mặc định, các luồng là luồng không daemon. Hướng dẫn này cung cấp một giải thích chi tiết kèm theo các ví dụ liên quan về luồng daemon trong lập trình Python.

Overview of Daemon Threads

Đôi khi, cần thiết phải thực hiện một nhiệm vụ trong nền. Một loại luồng đặc biệt được sử dụng cho các nhiệm vụ nền, gọi là luồng daemon. Nói cách khác, các luồng daemon thực hiện các nhiệm vụ trong nền. Những luồng này xử lý các nhiệm vụ không quan trọng mà có thể hữu ích cho ứng dụng nhưng không cản trở nó nếu chúng thất bại hoặc bị hủy giữa chừng.

Ngoài ra, một luồng daemon sẽ không có quyền kiểm soát khi nào nó bị kết thúc. Chương trình sẽ kết thúc ngay khi tất cả các luồng không phải daemon hoàn thành, ngay cả khi vẫn còn các luồng daemon đang chạy vào thời điểm đó.

Difference Between Daemon & Non-Daemon Threads

Daemon Non-daemon
A process will exit if only daemon threads are running (or if no threads are running). A process will not exit if at least one non-daemon thread is running.
Daemon threads are used for background tasks. Non-daemon threads are used for critical tasks.
Daemon threads are terminated abruptly. Non-daemon threads run to completion.

Các luồng daemon có thể thực hiện các tác vụ như −

  • Tạo một tệp để lưu trữ thông tin Log trong nền.

  • Thực hiện việc thu thập dữ liệu web trong nền.

  • Lưu dữ liệu tự động vào cơ sở dữ liệu ở chế độ nền.

Creating a Daemon Thread in Python

Để tạo một luồng daemon, bạn cần đặt thuộc tính daemon thành True trong hàm khởi tạo Thread .

t1=threading.Thread(daemon=True)

Mặc định, thuộc tính daemon được đặt là None. Nếu bạn thay đổi nó thành không phải None, daemon sẽ thiết lập rõ ràng xem luồng có phải là luồng daemon hay không.

Example

Hãy xem ví dụ sau để tạo một luồng daemon và kiểm tra xem luồng đó có phải là luồng daemon hay không bằng cách sử dụng thuộc tính 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)

Nó sẽ tạo ra output

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

Nếu một đối tượng luồng (thread) được tạo trong luồng chính mà không có bất kỳ tham số nào, thì luồng được tạo sẽ là luồng không daemon vì luồng chính không phải là luồng daemon. Do đó, tất cả các luồng được tạo trong luồng chính mặc định là không daemon. Tuy nhiên, chúng ta có thể thay đổi thuộc tính daemon thành True bằng cách sử dụng thuộc tính Thread.daemon trước starting the thread , không gì khác ngoài việc gọi phương thức start() .

Example

Dưới đây là một ví dụ −

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)

Khi thực thi chương trình trên, chúng ta sẽ nhận được đầu ra sau đây −

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

Managing the Daemon Thread Attribute

Nếu bạn cố gắng thiết lập trạng thái daemon của một luồng sau khi đã khởi động nó, thì một lỗi RuntimeError sẽ được phát sinh.

Example

Dưới đây là một ví dụ khác minh họa việc nhận được RuntimeError khi bạn cố gắng thiết lập trạng thái daemon của một luồng sau khi đã khởi động nó.

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)

Nó sẽ tạo ra output

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