امروزه، برنامهنویسان برای افزایش کارایی و سرعت برنامههای خود از تکنیکهای مختلفی برای اجرای همزمان وظایف استفاده میکنند. یکی از این تکنیکها، چندریسگی یا همان Multithreading است. این قابلیت به شما اجازه میدهد چندین کار را در یک زمان اجرا کنید، به خصوص در برنامههایی که نیاز به عملیات I/O یا پردازش موازی دارند. در این مقاله از سایت کداکسپلور، مفهوم چندریسگی در پایتون را بررسی کرده و نحوهی پیادهسازی آن را توضیح میدهیم.
آنچه در این مقاله میخوانید:
- تعریف «چندریسگی» و تفاوت آن با پردازش چندگانه
- نحوهی ایجاد ریسهها (Threads) در پایتون
- ابزارها و ماژولهای اصلی برای چندریسگی
- مثالهای کاربردی و رایج
- چالشها و مشکلات چندریسگی
- جمعبندی و نکات کلیدی
تعریف چندریسگی و تفاوت آن با پردازش چندگانه
پردازش چندگانه (Multiprocessing) به معنای اجرای همزمان چند فرآیند مستقل در سیستم عامل است، در حالی که چندریسگی به اجرای چندین ریسه (Thread) در یک فرآیند واحد اشاره دارد.
در چندریسگی، تمامی ریسهها منابع فرآیند (مانند حافظه) را به اشتراک میگذارند. این اشتراک منابع باعث سبکتر شدن اجرای ریسهها نسبت به فرآیندهای جداگانه میشود.
نحوهی ایجاد ریسهها در پایتون
برای پیادهسازی چندریسگی در پایتون، از ماژول threading
استفاده میشود. مراحل اصلی برای ایجاد و مدیریت ریسهها به شرح زیر است:
۱. ایمپورت ماژول
ابتدا باید ماژول threading
را ایمپورت کنید:
import threading
۲. تعریف یک تابع
تابعی که توسط ریسه اجرا میشود باید از قبل تعریف شده باشد:
def print_square(num): print(f"Square: {num * num}")
۳. ایجاد ریسه
برای ایجاد یک ریسه، از کلاس Thread
استفاده میکنیم و تابع را به عنوان هدف (target) تعیین میکنیم:
t1 = threading.Thread(target=print_square, args=(5,))
۴. اجرای ریسه
ریسه را با متد start()
اجرا میکنیم:
t1.start()
۵. انتظار برای پایان ریسه
برای اطمینان از تکمیل ریسه، از متد join()
استفاده میکنیم:
t1.join()
ابزارها و ماژولهای اصلی برای چندریسگی
۱. ماژول threading
این ماژول ابزارهایی مانند کلاس Thread
و Lock
را ارائه میدهد که برای ایجاد و هماهنگی ریسهها کاربرد دارند.
۲. ماژول concurrent.futures
برای سادهسازی مدیریت ریسهها، از کلاسهایی مانند ThreadPoolExecutor
استفاده میشود:
from concurrent.futures import ThreadPoolExecutor def task(): print("Task running") with ThreadPoolExecutor(max_workers=2) as executor: executor.submit(task) executor.submit(task)
مثالهای کاربردی
محاسبهی مربع و مکعب به صورت همزمان
در این مثال، از دو ریسه برای محاسبهی مربع و مکعب یک عدد به صورت همزمان استفاده میکنیم:
import threading def print_square(num): print(f"Square: {num * num}") def print_cube(num): print(f"Cube: {num * num * num}") if __name__ == "__main__": t1 = threading.Thread(target=print_square, args=(5,)) t2 = threading.Thread(target=print_cube, args=(5,)) t1.start() t2.start() t1.join() t2.join() print("Done!")
خروجی:
Square: 25 Cube: 125 Done!
چالشها و مشکلات چندریسگی
۱. شرایط مسابقه (Race Conditions)
وقتی دو یا چند ریسه به طور همزمان به دادههای مشترک دسترسی دارند، ممکن است نتایج غیرمنتظرهای رخ دهد.
۲. بنبست (Deadlock)
وقتی ریسهها منتظر آزاد شدن منابع توسط یکدیگر هستند، ممکن است هیچکدام ادامه ندهند.
۳. محدودیتهای GIL
قفل مفسر جهانی یا GIL در پایتون اجازه نمیدهد بیش از یک ریسه همزمان کد پایتون را اجرا کند. این محدودیت برای وظایف وابسته به پردازنده (CPU-bound) مشکلساز است.
جمعبندی
چندریسگی (Multithreading) یکی از مفاهیم کلیدی در بهبود عملکرد برنامههای پایتون است. با این حال، استفاده از این تکنیک نیازمند آگاهی کامل از چالشها و ابزارهای موجود است. در این مقاله، اصول چندریسگی را بررسی کرده و با مثالهایی کاربردی به توضیح آن پرداختیم.
نظر شما چیست؟ آیا تاکنون از چندریسگی در پروژههای خود استفاده کردهاید؟ تجربیات و سوالات خود را در بخش دیدگاهها با ما به اشتراک بگذارید!