آموزش پایتون - زمانبندی Threadها

زمان‌بندی تردها (Thread scheduling) در پایتون، فرآیند تصمیم‌گیری درباره این است که کدام ترد در هر لحظه اجرا شود. در یک برنامه چندتردی (multi-threaded)، چندین ترد به صورت مستقل اجرا می‌شوند که امکان اجرای موازی وظایف را فراهم می‌سازد. با این حال، پایتون دارای پشتیبانی داخلی برای کنترل مستقیم اولویت تردها یا سیاست‌های زمان‌بندی نیست. در عوض، به زمان‌بندی ترد سیستم‌عامل متکی است.

تردهای پایتون به تردهای بومی سیستم‌عامل میزبان نگاشت می‌شوند، مانند تردهای POSIX (یا pthreads) در سیستم‌های شبه‌یونیکس یا تردهای ویندوز. زمان‌بند سیستم‌عامل، اجرای این تردها از جمله تعویض زمینه (context switching)، اولویت‌های ترد و سیاست‌های زمان‌بندی را مدیریت می‌کند. پایتون قابلیت‌های پایه‌ای زمان‌بندی ترد را از طریق کلاس threading.Timer و ماژول sched ارائه می‌دهد.

در این آموزش، مفاهیم پایه زمان‌بندی ترد در پایتون را خواهید آموخت، از جمله نحوه استفاده از ماژول sched برای زمان‌بندی وظایف و کلاس threading.Timer برای اجرای با تاخیر توابع.

زمان‌بندی تردها با استفاده از کلاس Timer

کلاس Timer از ماژول threading در پایتون به شما امکان می‌دهد فراخوانی یک تابع را برای اجرا پس از مدت زمان مشخصی زمان‌بندی کنید. این کلاس یک زیرکلاس از Thread است و به عنوان نمونه‌ای برای ایجاد تردهای سفارشی عمل می‌کند.

شما یک تایمر را مشابه تردها با فراخوانی متد start() آن آغاز می‌کنید. در صورت نیاز، می‌توانید پیش از شروع تایمر، آن را با استفاده از متد cancel() متوقف کنید. توجه داشته باشید که تاخیر واقعی پیش از اجرای اقدام ممکن است دقیقاً با بازه زمانی مشخص‌شده مطابقت نداشته باشد.

مثال

این مثال نحوه استفاده از کلاس threading.Timer() برای زمان‌بندی و مدیریت اجرای وظایف (تردهای سفارشی) در پایتون را نشان می‌دهد.

import threading
import time

# Define the event function
def schedule_event(name, start):
   now = time.time()
   elapsed = int(now - start)
   print('Elapsed:', elapsed, 'Name:', name)

# Start time
start = time.time()
print('START:', time.ctime(start))

# Schedule events using Timer
t1 = threading.Timer(3, schedule_event, args=('EVENT_1', start))
t2 = threading.Timer(2, schedule_event, args=('EVENT_2', start))

# Start the timers
t1.start()
t2.start()

t1.join()
t2.join()
# End time
end = time.time()
print('End:', time.ctime(end))

با اجرای برنامه بالا، خروجی زیر تولید خواهد شد −

START: Tue Jul  2 14:46:33 2024
Elapsed: 2 Name: EVENT_2
Elapsed: 3 Name: EVENT_1
End: Tue Jul  2 14:46:36 2024

زمان‌بندی تردها با استفاده از ماژول sched

ماژول sched در کتابخانه استاندارد پایتون، روشی را برای زمان‌بندی وظایف ارائه می‌دهد. این ماژول یک زمان‌بند رویداد عمومی را برای اجرای وظایف در زمان‌های مشخص پیاده‌سازی می‌کند و ابزارهای مشابهی مانند زمان‌بندی وظایف (task scheduler) در ویندوز یا لینوکس ارائه می‌دهد.

کلاس‌ها و متدهای کلیدی ماژول sched

کلاس scheduler() که در ماژول sched تعریف شده است، برای ایجاد یک شیء زمان‌بند استفاده می‌شود. در ادامه سینتکس این کلاس آمده است −

scheduler(timefunc=time.monotonic, delayfunc=time.sleep)

متدهای تعریف‌شده در کلاس scheduler عبارت‌اند از −

  • scheduler.enter(delay, priority, action, argument=(), kwargs={}) − رویدادها می‌توانند برای اجرا پس از یک تاخیر یا در یک زمان مشخص زمان‌بندی شوند. برای زمان‌بندی آن‌ها با تاخیر، از متد enter() استفاده می‌شود.

  • scheduler.cancel(event) − حذف رویداد از صف. اگر رویداد مورد نظر در حال حاضر در صف نباشد، این متد خطای ValueError ایجاد می‌کند.

  • scheduler.run(blocking=True) − اجرای تمام رویدادهای زمان‌بندی‌شده.

رویدادها می‌توانند برای اجرا پس از یک تاخیر یا در زمان مشخصی زمان‌بندی شوند. برای زمان‌بندی آن‌ها با تاخیر، از متد enter() استفاده کنید که چهار آرگومان می‌گیرد.

  • عددی که نشان‌دهنده میزان تاخیر است

  • یک مقدار اولویت

  • تابعی که باید فراخوانی شود

  • یک تاپل از آرگومان‌ها برای تابع

مثال

این مثال نحوه زمان‌بندی رویدادها برای اجرا پس از یک تاخیر را با استفاده از ماژول sched نشان می‌دهد. این کد دو رویداد مختلف را زمان‌بندی می‌کند −

import sched
import time

scheduler = sched.scheduler(time.time, time.sleep)

def schedule_event(name, start):
   now = time.time()
   elapsed = int(now - start)
   print('elapsed=',elapsed, 'name=', name)

start = time.time()
print('START:', time.ctime(start))
scheduler.enter(2, 1, schedule_event, ('EVENT_1', start))
scheduler.enter(5, 1, schedule_event, ('EVENT_2', start))

scheduler.run()

# End time
end = time.time()
print('End:', time.ctime(end))

این برنامه خروجی زیر را تولید خواهد کرد −

START: Tue Jul  2 15:11:48 2024
elapsed= 2 name= EVENT_1
elapsed= 5 name= EVENT_2
End: Tue Jul  2 15:11:53 2024

مثال

برای درک بهتر این مفهوم، به مثال دیگری توجه کنید. این مثال یک تابع را برای انجام یک جمع پس از ۴ ثانیه تاخیر با استفاده از ماژول sched در پایتون زمان‌بندی می‌کند.

import sched
from datetime import datetime
import time

def addition(a,b):
   print("Performing Addition : ", datetime.now())
   print("Time : ", time.monotonic())
   print("Result {}+{} =".format(a, b), a+b)

s = sched.scheduler()

print("Start Time : ", datetime.now())

event1 = s.enter(4, 1, addition, argument = (5,6))
print("Event Created : ", event1)
s.run()
print("End Time : ", datetime.now())

این برنامه خروجی زیر را تولید خواهد کرد −

Start Time :  2024-07-02 15:18:27.862524
Event Created :  Event(time=2927111.05638099, priority=1, sequence=0, action=<function addition at 0x7f31f902bd90>, argument=(5, 6), kwargs={})
Performing Addition :  2024-07-02 15:18:31.866381
Time :  2927111.060294749
Result 5+6 = 11
End Time :  2024-07-02 15:18:31.866545

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