ماژول asyncio
یکی از ماژولهای مهم در پایتون است که برای برنامهنویسی غیرهمزمان (asynchronous programming) استفاده میشود. این ماژول امکاناتی را فراهم میکند که میتوان بهوسیلهی آنها برنامههای همزمان و مقاوم در برابر مسدودشدگی (non-blocking) نوشت. به عبارت دیگر، asyncio
امکان اجرای همزمان چندین وظیفه (task) را به صورت موازی فراهم میکند، بدون اینکه نیاز باشد به روشهای سنتی مانند نخها (threads) یا فرآیندها (processes) متوسل شویم.
ابتدای توسعه و نسخههای اولیه
در سالهای اولیه، برنامهنویسی غیرهمزمان در پایتون با استفاده از ماژولهایی مانند threading
و multiprocessing
انجام میشد که هر دو روش به دلیل نیاز به هماهنگی بین نخها یا فرآیندها مشکلاتی مانند پیچیدگی و هزینههای بالا داشتند.
در سال 2008، پایتون 3.0 معرفی شد که بهبودهایی در زبان و امکانات آن ارائه میکرد. با این حال، هنوز ابزارهای کاملی برای برنامهنویسی غیرهمزمان وجود نداشت.
پیشنهاد و توسعه asyncio
گیویدو ون روسوم (Guido van Rossum)، خالق پایتون، به همراه چند نفر دیگر تصمیم گرفتند تا رویکرد جدیدی برای مدیریت همزمانی و I/O غیرهمزمان در پایتون معرفی کنند.
PEP 3156، که با نام "Asynchronous IO Support Rebooted: the 'asyncio' Module" شناخته میشود، در سال 2013 توسط گیویدو ون روسوم ارائه شد. این PEP به معرفی asyncio
به عنوان یک ماژول استاندارد برای مدیریت I/O غیرهمزمان و همزمانی پرداخت.
معرفی در پایتون 3.4
asyncio
به طور رسمی در پایتون 3.4 که در سال 2014 منتشر شد، معرفی گردید. این ماژول شامل ابزارهایی برای مدیریت کوروتینها، وظایف، رویداد لوپ و امکاناتی دیگر برای برنامهنویسی غیرهمزمان بود.
با معرفی asyncio
، برنامهنویسان پایتون توانستند به راحتی برنامههای غیرهمزمانی بنویسند که به صورت موثر و کارآمد عمل میکردند.
تکامل و بهبودها
در نسخههای بعدی پایتون، بهبودهای زیادی به asyncio
افزوده شد. در پایتون 3.5، کلمات کلیدی async
و await
معرفی شدند که نوشتن کوروتینها و مدیریت همزمانی را سادهتر و خواناتر کردند.
نسخههای بعدی پایتون، مانند 3.6 و 3.7، نیز بهبودهایی در کارایی و امکانات asyncio
اضافه کردند. امکاناتی مانند async generators
، async comprehensions
و بهبودهای عملکردی در رویداد لوپ.
تکامل در پایتون 3.8 و بعد از آن
در پایتون 3.8 و بعد از آن، asyncio
همچنان به تکامل و بهبود ادامه داد. امکانات جدیدی مانند asyncio.run
برای اجرای راحتتر برنامههای غیرهمزمان و بهبودهای بیشتری در هماهنگکنندهها و ابزارهای همزمانی اضافه شد.
ماژول asyncio
از زمان معرفی خود به یکی از اجزای مهم و پرکاربرد پایتون تبدیل شده است و به برنامهنویسان اجازه میدهد که برنامههای قدرتمند و کارآمدی برای مدیریت همزمانی و I/O غیرهمزمان بنویسند.
اجزای اصلی ماژول asyncio
رویداد لوپ (Event Loop): قلب asyncio
است. رویداد لوپ مسئول اجرای وظایف (tasks) و هندل کردن رویدادهای I/O است.
loop = asyncio.get_event_loop()
loop.run_until_complete(some_coroutine())
کوروتینها (Coroutines): توابع خاصی هستند که با استفاده از کلمه کلیدی async
تعریف میشوند و میتوانند با کلمه کلیدی await
اجرای خود را به حالت تعلیق درآورند تا زمانی که نتیجهی یک عملیات I/O آماده شود.
async def my_coroutine():
await asyncio.sleep(1)
print("Hello, world!")
وظایف (Tasks): نمایندهی اجرای یک کوروتین است. وظایف به رویداد لوپ سپرده میشوند تا اجرا شوند.
task = asyncio.create_task(my_coroutine())
آیندهها (Futures): اشیائی هستند که نمایانگر نتیجهی یک عملیات غیرهمزمان در آینده هستند. معمولاً کاربران asyncio
مستقیماً از آنها استفاده نمیکنند، بلکه با کوروتینها و وظایف کار میکنند که بر اساس آیندهها ساخته شدهاند.
future = loop.create_future()
انتظارها (Awaitables): هر شیءای که بتوان آن را با کلمه کلیدی await
منتظر ماند، شامل کوروتینها، وظایف و آیندهها.
result = await some_coroutine()
هماهنگکنندهها (Synchronizers): ابزارهایی مانند asyncio.Lock
, asyncio.Event
, asyncio.Condition
و asyncio.Semaphore
برای هماهنگی و همگامسازی وظایف.
lock = asyncio.Lock()
async with lock:
# critical section
انتقالدهندهها (Transports) و پروتکلها (Protocols): لایههای سطح پایین برای مدیریت اتصالات شبکه و I/O. برای کار با سوکتها و پروتکلهای شبکهای استفاده میشوند.
در کل، asyncio
به شما امکان میدهد که برنامههایی بنویسید که بتوانند کارهای مختلف را به صورت همزمان و بهینه انجام دهند، بدون اینکه نیاز به روشهای مسدود کننده و پرهزینه مانند threads یا فرآیندهای سنتی باشد.