آشنایی با coroutine

  • مدرس: علی بیگدلی
  • تاریخ انتشار: 1403/05/11
  • تعداد بازدید: 153

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

تعریف یک Coroutine

یک coroutine با استفاده از کلمات کلیدی async و await تعریف می‌شود. برای تبدیل یک تابع به coroutine، از کلمه کلیدی async قبل از تعریف تابع استفاده می‌کنیم. برای متوقف کردن اجرای coroutine تا زمانی که نتیجه یک عملیات غیرهمزمان آماده شود، از await استفاده می‌کنیم.

برای شروع، یک تابع ساده می‌نویسیم که از time.sleep برای ایجاد تأخیر استفاده می‌کند:

import time

def sync_sleep():
    print("Start sleeping...")
    time.sleep(2)
    print("Done sleeping!")

این تابع به صورت همزمان (synchronous) اجرا می‌شود و وقتی که time.sleep(2) فراخوانی می‌شود، برنامه به مدت 2 ثانیه مسدود می‌شود. حالا می‌خواهیم این تابع را به یک تابع غیرهمزمان (asynchronous) تبدیل کنیم.

مرحله 1: تعریف تابع غیرهمزمان

ابتدا، تابع را به یک coroutine تبدیل می‌کنیم. برای این کار از کلمات کلیدی async و await استفاده می‌کنیم.

import asyncio

async def async_sleep():
    print("Start sleeping...")
    await asyncio.sleep(2)
    print("Done sleeping!")

در اینجا، async def نشان‌دهنده این است که async_sleep یک coroutine است. await asyncio.sleep(2) به جای time.sleep(2) استفاده می‌شود تا برنامه به صورت غیرهمزمان به مدت 2 ثانیه متوقف شود.

مرحله 2: بررسی نوع تابع

برای نشان دادن اینکه این تابع یک coroutine است که هنوز اجرا نشده است، می‌توانیم آن را فراخوانی کرده و نوع آن را چاپ کنیم:

<coroutine object async_sleep at 0x...>

مرحله 3: اجرای coroutine در رویداد لوپ

asyncio.run در پایتون برای ساده‌سازی اجرای برنامه‌های غیرهمزمان ایجاد شده است. این تابع با راه‌اندازی و مدیریت خودکار رویداد لوپ، اجرای coroutine اصلی، و سپس بستن و پاکسازی صحیح رویداد لوپ پس از اتمام، به کاهش پیچیدگی و احتمال بروز خطاهای مدیریتی کمک می‌کند. به طور خلاصه، `asyncio.run` اجرای برنامه‌های غیرهمزمان را راحت‌تر، ایمن‌تر و خواناتر می‌کند، به خصوص در اسکریپت‌های ساده و تست‌ها. برای اجرای یک coroutine، باید از رویداد لوپ asyncio استفاده کنیم. برای این کار از تابع asyncio.run استفاده می‌کنیم:

asyncio.run(async_sleep())

این کد رویداد لوپ را اجرا می‌کند و coroutine async_sleep را تا زمانی که تکمیل شود اجرا می‌کند.

کد کامل و توضیح هر بخش

حال کل کد را به همراه توضیحات مرحله به مرحله بررسی می‌کنیم:

import asyncio

# 1. تعریف تابع غیرهمزمان
async def async_sleep():
    print("Start sleeping...")
    await asyncio.sleep(2)  # 2. استفاده از await برای انتظار غیرهمزمان
    print("Done sleeping!")

# 3. بررسی نوع coroutine
coro = async_sleep()
print(coro)  # خروجی: <coroutine object async_sleep at 0x...>

# 4. اجرای coroutine در رویداد لوپ
asyncio.run(coro)  # استفاده از asyncio.run برای اجرای coroutine

توضیحات

تعریف تابع غیرهمزمان:

  • async def async_sleep(): این خط نشان می‌دهد که async_sleep یک تابع غیرهمزمان (coroutine) است.
  • await asyncio.sleep(2): این خط برنامه را به صورت غیرهمزمان به مدت 2 ثانیه متوقف می‌کند بدون اینکه کل برنامه مسدود شود.

بررسی نوع coroutine:

  • coro = async_sleep(): این خط coroutine را ایجاد می‌کند اما آن را اجرا نمی‌کند.
  • print(coro): این خط نشان می‌دهد که coro یک شیء coroutine است که هنوز اجرا نشده است.

اجرای coroutine در رویداد لوپ:

  • asyncio.run(coro): این خط رویداد لوپ را اجرا می‌کند و coroutine coro را تا زمانی که تکمیل شود اجرا می‌کند.

این مراحل نشان می‌دهد که چگونه یک تابع همزمان با استفاده از time.sleep به یک تابع غیرهمزمان با استفاده از asyncio.sleep تبدیل می‌شود و چگونه این تابع غیرهمزمان اجرا می‌شود.


ثبت دیدگاه


نکته: آدرس ایمیل شما منتشر نخواهد شد

دیدگاه کاربران (0)


هیچ دیدگاهی ثبت نشده است می توانید اولین نفر باشید