آموزش پایتون - نخ‌های دیمون

نخ‌های دیمون (Daemon threads) در پایتون برای اجرای وظایف پس‌زمینه که برای عملکرد برنامه حیاتی نیستند، مفید هستند. آن‌ها به شما اجازه می‌دهند تا وظایف را در پس‌زمینه اجرا کنید بدون اینکه نگران پیگیری آن‌ها باشید.

پایتون دو نوع نخ ارائه می‌دهد: نخ‌های غیردیمون (non-daemon) و نخ‌های دیمون (daemon). به طور پیش‌فرض، نخ‌ها از نوع غیردیمون هستند. این آموزش یک توضیح مفصل همراه با مثال‌های مرتبط درباره نخ‌های دیمون در برنامه‌نویسی پایتون ارائه می‌دهد.

بررسی اجمالی نخ‌های دیمون

گاهی اوقات لازم است یک وظیفه در پس‌زمینه اجرا شود. برای وظایف پس‌زمینه از نوع خاصی از نخ استفاده می‌شود که نخ دیمون نامیده می‌شود. به عبارت دیگر، نخ‌های دیمون وظایف را در پس‌زمینه اجرا می‌کنند. این نخ‌ها وظایف غیرحیاتی را مدیریت می‌کنند که ممکن است برای برنامه مفید باشند، اما اگر شکست بخورند یا در میان کار لغو شوند، به برنامه آسیبی نمی‌رسانند.

همچنین، یک نخ دیمون کنترلی بر زمان پایان یافتن خود نخواهد داشت. برنامه به محض اینکه تمام نخ‌های غیردیمون به پایان برسند خاتمه می‌یابد، حتی اگر در آن لحظه نخ‌های دیمون هنوز در حال اجرا باشند.

تفاوت بین نخ‌های دیمون و غیردیمون

دیمون غیردیمون
اگر فقط نخ‌های دیمون در حال اجرا باشند (یا هیچ نخی در حال اجرا نباشد)، فرآیند خارج می‌شود. اگر حداقل یک نخ غیردیمون در حال اجرا باشد، فرآیند خارج نمی‌شود.
نخ‌های دیمون برای وظایف پس‌زمینه استفاده می‌شوند. نخ‌های غیردیمون برای وظایف حیاتی استفاده می‌شوند.
نخ‌های دیمون به طور ناگهانی متوقف می‌شوند. نخ‌های غیردیمون تا تکمیل کامل اجرا می‌شوند.

نخ‌های دیمون می‌توانند وظایفی مانند موارد زیر را انجام دهند −

  • ایجاد فایلی که اطلاعات ثبت رویدادها (Log) را در پس‌زمینه ذخیره می‌کند.

  • انجام استخراج داده‌های وب (Web Scraping) در پس‌زمینه.

  • ذخیره‌سازی خودکار داده‌ها در پایگاه داده در پس‌زمینه.

ایجاد یک نخ دیمون در پایتون

برای ایجاد یک نخ دیمون، باید ویژگی daemon را در سازنده Thread برابر با 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

اگر یک شیء نخ در نخ اصلی (Main Thread) بدون هیچ پارامتری ایجاد شود، نخ ایجادشده یک نخ غیردیمون خواهد بود زیرا نخ اصلی یک نخ دیمون نیست. بنابراین، تمام نخ‌های ایجادشده در نخ اصلی به طور پیش‌فرض غیردیمون هستند. با این حال، می‌توانیم ویژگی daemon را قبل از شروع نخ، یعنی قبل از فراخوانی متد ()start، با استفاده از ویژگی Thread.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

پیشرفت مطالعه: وضعیت خوانده‌شدن این درس فقط در همین مرورگر ذخیره می‌شود؛ بدون نیاز به حساب کاربری.