پردازش موازی و همزمانی در پایتون
پردازش موازی و همزمانی از جمله مفاهیم مهم در دنیای برنامهنویسی هستند که به ویژه در زمانهایی که نیاز به انجام چندین کار به طور همزمان یا با سرعت بیشتر وجود دارد، کاربرد فراوانی دارند. پایتون نیز ابزارهایی برای انجام پردازش موازی و همزمانی فراهم میکند که میتوانند به افزایش کارایی و بهینهسازی کد کمک کنند.
۱. تفاوت بین پردازش موازی (Parallel Processing) و همزمانی (Concurrency)
-
پردازش موازی: در پردازش موازی، چندین فرآیند (process) به طور همزمان اجرا میشوند و معمولاً به استفاده از چندین هسته پردازنده (CPU) نیاز دارد. هر فرآیند در پردازش موازی مستقل از دیگری اجرا میشود و قادر است منابع سیستم را به طور همزمان استفاده کند.
-
همزمانی: همزمانی به معنای اجرای چندین کار (task) به نظر همزمان است، اما ممکن است همه این کارها در یک هسته پردازنده انجام شوند. به عبارت دیگر، در همزمانی، سیستم در هر لحظه فقط یک کار را انجام میدهد، اما آنقدر سریع سوئیچ بین وظایف را انجام میدهد که به نظر میرسد همه کارها به صورت همزمان در حال اجرا هستند.
۲. پردازش موازی در پایتون
پایتون برای پردازش موازی ابزارهایی نظیر ماژول multiprocessing و concurrent.futures دارد که به شما امکان میدهند تا از چندین هسته پردازنده برای انجام محاسبات سنگین استفاده کنید.
ماژول multiprocessing
ماژول multiprocessing به شما این امکان را میدهد که فرآیندهای جداگانهای راهاندازی کرده و آنها را به طور همزمان اجرا کنید.
مثال:
def worker(n):
return n * n
if __name__ == '__main__':
with multiprocessing.Pool(processes=4) as pool:
results = pool.map(worker, [1, 2, 3, 4, 5])
print(results) # خروجی: [1, 4, 9, 16, 25]
در این مثال، از Pool برای ایجاد یک مجموعه از فرآیندها استفاده شده است که به صورت موازی وظایف را اجرا میکنند.
ماژول concurrent.futures
ماژول concurrent.futures به شما این امکان را میدهد که به راحتی وظایف را به صورت موازی اجرا کنید و از دو نوع ThreadPoolExecutor و ProcessPoolExecutor استفاده کنید.
- ThreadPoolExecutor برای همزمانی با استفاده از نخها (threads) استفاده میشود.
- ProcessPoolExecutor برای پردازش موازی با استفاده از فرآیندها (processes) است.
مثال استفاده از ProcessPoolExecutor:
def worker(n):
return n * n
with ProcessPoolExecutor() as executor:
results = list(executor.map(worker, [1, 2, 3, 4, 5]))
print(results) # خروجی: [1, 4, 9, 16, 25]
۳. همزمانی در پایتون
همزمانی در پایتون معمولاً با استفاده از نخها (threads) پیادهسازی میشود. برای این کار، میتوان از ماژولهای threading و asyncio استفاده کرد.
ماژول threading
ماژول threading به شما این امکان را میدهد که نخهای مختلفی برای انجام کارها به طور همزمان داشته باشید. این نخها میتوانند برای انجام کارهایی که منتظر زمان هستند (مثل ورودی/خروجی) مفید باشند.
مثال استفاده از threading:
def worker(n):
print(f"Working on {n}")
threads = []
for i in range(5):
thread = threading.Thread(target=worker, args=(i,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
در این مثال، پنج نخ مختلف به طور همزمان ایجاد و اجرا میشوند.
ماژول asyncio
برای انجام همزمانی به روش غیرهمزمان (asynchronous)، پایتون از ماژول asyncio استفاده میکند. این ماژول به شما این امکان را میدهد که از کدهای غیرهمزمان برای انجام کارهایی مانند انجام درخواستهای HTTP یا عملیات ورودی/خروجی استفاده کنید.
مثال استفاده از asyncio:
async def worker(n):
print(f"Working on {n}")
await asyncio.sleep(1) # شبیهسازی عملیات غیرهمزمان
print(f"Finished {n}")
async def main():
tasks = []
for i in range(5):
tasks.append(worker(i))
await asyncio.gather(*tasks)
asyncio.run(main())
در این مثال، از asyncio.sleep() برای شبیهسازی یک عملیات غیرهمزمان استفاده شده است. این عملیات بهطور همزمان انجام میشود.
۴. تفاوت بین پردازش موازی و همزمانی در پایتون
-
پردازش موازی: برای بهرهبرداری از چندین هسته پردازنده و انجام محاسبات سنگین و مستقل از یکدیگر مفید است. این پردازشها از فرآیندهای مستقل استفاده میکنند و به صورت واقعی به طور همزمان اجرا میشوند.
-
همزمانی: معمولاً برای انجام وظایف ورودی/خروجی (I/O-bound) استفاده میشود. این کار از نخها یا عملیات غیرهمزمان برای اجرای چندین کار به نظر همزمان استفاده میکند، اما در واقع همه کارها به طور همزمان در یک هسته پردازنده انجام نمیشوند.
۵. انتخاب مناسب بین پردازش موازی و همزمانی
- اگر برنامه شما نیاز به انجام محاسبات سنگین و پردازشهای موازی دارد (مثل پردازش دادههای بزرگ)، از پردازش موازی استفاده کنید.
- اگر برنامه شما نیاز به انجام کارهایی با تأخیر کم مانند دسترسی به شبکه یا فایلها دارد، همزمانی مناسبتر است.
۶. جمعبندی
در پایتون، ابزارهای مختلفی برای پردازش موازی و همزمانی وجود دارد. ماژولهایی مانند multiprocessing و concurrent.futures برای پردازش موازی استفاده میشوند، در حالی که ماژولهای threading و asyncio برای همزمانی به کار میروند. انتخاب ابزار مناسب بستگی به نوع وظایف شما دارد. پردازش موازی برای پردازشهای سنگین و محاسباتی مناسب است، در حالی که همزمانی برای کارهای ورودی/خروجی مفیدتر است.
