پاسخ تمرینات ماژول Asyncio (معرفی) در پایتون

Please login to bookmark Close


پاسخ تمرین ۱

هر ترد در پایتون حافظه‌ی قابل‌توجهی (معمولاً چند مگابایت برای پشته) مصرف می‌کند و سیستم‌عامل هم نمی‌تواند بیست‌هزار ترد را به‌خوبی مدیریت کند. علاوه بر این، هماهنگی بین این‌همه ترد و جمع‌آوری نتایجشان خودش یک مشکل بزرگ جدید ایجاد می‌کند.

پاسخ تمرین ۲

هم‌روال تابعی است که می‌تواند در میانه‌ی اجرا متوقف شود و بعداً از همان نقطه، بدون از دست دادن وضعیتش، ادامه یابد. در داستان صبحانه «شما» نقش حلقه‌ی رویداد (event loop) را بازی می‌کنید: ناظر و برنامه‌ریزی که سفارش‌ها را شروع می‌کند، می‌خوابد و با رسیدن هر سفارش بیدار می‌شود. (خودِ «دستورالعملِ زنگ‌زدن و سفارش‌دادن و منتظرماندن» همان coroutine است.)

پاسخ تمرین ۳

  • coroutine: تابعی که می‌تواند وسط اجرا مکث و بعداً ادامه یابد (با async def).
  • event loop: ناظری که کارهای آماده را اجرا و کارهای منتظر را کنار می‌گذارد.
  • Task: هم‌روالی که در حلقه ثبت شده تا اجرا شود.
  • awaiting: اعلام «نمی‌توانم ادامه دهم تا X فراهم شود» و بازگرداندن کنترل به حلقه.

پاسخ تمرین ۴

زنگ در معادل یک رویداد ورودی/خروجی است (مثل رسیدن داده روی یک سوکت). همین رویداد سیستم‌عامل را بیدار می‌کند و سیستم‌عامل هم حلقه‌ی رویداد را. وقتی حلقه بیدار شد، Task مربوطه را از مجموعه‌ی «در انتظار» به صف «آماده» منتقل می‌کند تا دوباره اجرا شود.

پاسخ تمرین ۵

حلقه فقط وقتی می‌خوابد که هیچ Task آماده‌ای در صف نباشد؛ در آن حالت به سیستم‌عامل می‌گوید تا رسیدن یک رویداد I/O او را بیدار نکند و در تماسی مثل epoll_wait منتظر می‌ماند. اگر حتی یک Task آماده باشد، حلقه بدون تأخیر آن را اجرا می‌کند و اصلاً نمی‌خوابد. این خواب هیچ CPU مصرف نمی‌کند.

پاسخ تمرین ۶

time.sleep کل ترد و بنابراین کل حلقه‌ی رویداد را بلاک می‌کند و مانع پیشرفت بقیه‌ی کارها می‌شود. به‌جای آن از await asyncio.sleep(...) استفاده می‌کنیم که غیرمسدودکننده است و کنترل را به حلقه بازمی‌گرداند.

پاسخ تمرین ۷

import asyncio
import time

async def order(item, seconds):
    print(f"ordering {item}...")
    await asyncio.sleep(seconds)
    print(f"{item} delivered")
    return item

async def main():
    start = time.time()
    results = await asyncio.gather(
        order("bread", 2),
        order("milk", 1),
        order("juice", 3),
    )
    print(results, "in %.1fs" % (time.time() - start))

asyncio.run(main())   # ~3s (the longest), not 6s

پاسخ تمرین ۸

import asyncio
import time

async def health_check(server_id):
    await asyncio.sleep(1)
    return (server_id, "ok")

async def main():
    start = time.time()
    tasks = [asyncio.create_task(health_check(i)) for i in range(200)]
    results = await asyncio.gather(*tasks)
    print(f"checked {len(results)} servers in %.2fs" % (time.time() - start))

asyncio.run(main())   # ~1s
Please login to bookmark Close
نظرات

دیدگاهتان را بنویسید

فهرست مطالب

سرفصل دوره

تمرین

این قسمت تمرین ندارد!

پاسخ تمرین ها

هنوز برای تمرین‌های این قسمت پاسخی ثبت نشده است!

اشتراک گذاری

چرا بهتره از فیلترشکن استفاده کنید؟

من همه ویدئو ها و پادکست های کُدباز رو توی یوتیوب و ساندکلود و پلتفرم هایی آپلود می‌کنم که اغلب فیلتر هستند.

اغلب آموزش‌ها ویدئو و پادکست دارند. پس اگر می‌خواهید از محتوای سایت بیشترین استفاده رو ببرید نیاز به فیلتر شکن دارید.

توجه داشته باشید که برای خرید از فروشگاه بهتره فیلتر شکن رو خاموش کنید.

تنظیمات

انتخاب زبان
تغییر تم