متوقف سازی با Cancel

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

در برنامه‌نویسی غیرهمزمان با استفاده از asyncio در پایتون، گاهی نیاز است که یک task (وظیفه) را قبل از تکمیل متوقف کنیم. برای این کار، از متد cancel استفاده می‌شود که به شما اجازه می‌دهد اجرای یک task را به طور ایمن و کنترل‌شده متوقف کنید.

استفاده از cancel

متد cancel برای متوقف کردن یک task در asyncio استفاده می‌شود. زمانی که این متد را فراخوانی می‌کنید، یک استثنا (asyncio.CancelledError) در task هدف ارسال می‌شود که می‌توان آن را مدیریت کرد تا منابع به درستی آزاد شوند یا عملیات‌های پاکسازی انجام شوند.

نحوه استفاده

در اینجا مثالی برای استفاده از cancel در asyncio آورده شده است:

import asyncio

async def my_coroutine():
    try:
        print("Coroutine started")
        await asyncio.sleep(10)  # یک عملیات طولانی
        print("Coroutine ended")
    except asyncio.CancelledError:
        print("Coroutine was cancelled")
        # انجام عملیات‌های پاکسازی
        raise

async def main():
    task = asyncio.create_task(my_coroutine())
    await asyncio.sleep(1)  # صبر برای مدت کوتاه
    task.cancel()  # لغو task
    try:
        await task  # منتظر task باشید تا لغو شود
    except asyncio.CancelledError:
        print("main: Task has been cancelled")

asyncio.run(main())

توضیحات

تعریف coroutine با مدیریت استثنا:

my_coroutine: یک coroutine که منتظر 10 ثانیه می‌ماند. اگر لغو شود، asyncio.CancelledError را مدیریت می‌کند و پیام مناسبی چاپ می‌کند.

ایجاد و لغو task:

  • task = asyncio.create_task(my_coroutine()): ایجاد یک task برای اجرای my_coroutine.
  • await asyncio.sleep(1): صبر برای 1 ثانیه قبل از لغو task.
  • task.cancel(): لغو task.
  • await task: منتظر می‌مانیم تا task لغو شده کامل شود و استثنا را مدیریت می‌کنیم.

نکات مهم

  • مدیریت CancelledError: هنگام لغو یک task، asyncio.CancelledError در آن task ارسال می‌شود. باید این استثنا را مدیریت کنید تا مطمئن شوید منابع به درستی آزاد می‌شوند.
  • پاکسازی: اگر task شامل عملیات‌هایی باشد که نیاز به پاکسازی دارند (مثل بستن فایل‌ها یا اتصالات شبکه)، باید این عملیات‌ها را در بلوک except انجام دهید.
  • لغو ایمن: همیشه پس از لغو یک task، با استفاده از await task منتظر بمانید تا task به درستی پایان یابد.

مثال پیچیده‌تر

در یک مثال پیچیده‌تر، می‌توانیم نشان دهیم که چگونه چندین task را لغو کنیم:

import asyncio

async def worker(name, duration):
    try:
        print(f"Worker {name} started")
        await asyncio.sleep(duration)
        print(f"Worker {name} finished")
    except asyncio.CancelledError:
        print(f"Worker {name} was cancelled")
        raise

async def main():
    tasks = [
        asyncio.create_task(worker("A", 3)),
        asyncio.create_task(worker("B", 5)),
        asyncio.create_task(worker("C", 7)),
    ]
    
    await asyncio.sleep(4)  # صبر برای مدت کوتاه
    for task in tasks:
        task.cancel()  # لغو همه taskها
    
    await asyncio.gather(*tasks, return_exceptions=True)  # مدیریت لغو همه taskها

asyncio.run(main())

در این مثال، سه task با زمان‌های مختلف ایجاد می‌شوند و بعد از 4 ثانیه، همه آن‌ها لغو می‌شوند. خروجی نشان می‌دهد که task‌ها به درستی لغو شده و پیام‌های مربوط به لغو چاپ می‌شوند. در نهایت استفاده از cancel در asyncio ابزاری قدرتمند برای مدیریت task‌ها و لغو آن‌ها به صورت ایمن و کنترل‌شده است. با استفاده از این قابلیت، می‌توانید برنامه‌های غیرهمزمان پیچیده و قابل اطمینان‌تری بنویسید که به درستی با شرایط لغو و پاکسازی منابع مقابله می‌کنند.


ثبت دیدگاه


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

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


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