ماژول 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 یا فرآیندهای سنتی باشد.