پاسخ تمرینات آموزش ماژول concurrent.futures – کلاس ThreadPoolExecutor

Please login to bookmark Close


پاسخ تمرین ۱

این پارامتر حداکثر تعداد تردهایی را که می‌توانند در یک لحظه هم‌زمان اجرا شوند مشخص می‌کند؛ کارهای بیشتر در صف می‌مانند تا یک ترد آزاد شود.

پاسخ تمرین ۲

چون آن executor فقط اجازه‌ی اجرای هم‌زمان دو ترد را داده (max_workers=2)؛ پس سومین تسک باید منتظر بماند تا یکی از دو تسک در حال اجرا به پایان برسد و یک ترد آزاد شود.

پاسخ تمرین ۳

executor.map برای اعمال سریع یک تابع روی یک لیست ورودی مناسب است، اما executor.submit هر تسک را تک‌به‌تک ارسال می‌کند و یک شیء Future برمی‌گرداند که بعداً می‌توانیم از آن استفاده کنیم.

پاسخ تمرین ۴

با فراخوانی future.result() روی هر Futureای که از submit برگشته، مقدار بازگشتی تسک را می‌گیریم.

پاسخ تمرین ۵

import time
from concurrent.futures import ThreadPoolExecutor

def task(name):
    print(f"Task {name} started")
    time.sleep(1)
    print(f"Task {name} finished")

with ThreadPoolExecutor(max_workers=2) as executor:
    executor.map(task, [1, 2, 3, 4, 5])

چون max_workers=2 است، فقط دو ترد در استخر وجود دارد؛ پس در هر لحظه حداکثر دو کار اجرا می‌شود و کار بعدی تا آزادشدن یک ترد شروع نمی‌شود.

پاسخ تمرین ۶

import time
from concurrent.futures import ThreadPoolExecutor

def task(name):
    time.sleep(1)
    return f"Result of task {name}"

with ThreadPoolExecutor(max_workers=2) as executor:
    futures = [executor.submit(task, i) for i in [1, 2, 3, 4]]
    results = [future.result() for future in futures]
    print("Results:", results)

پاسخ تمرین ۷

import time
from concurrent.futures import ThreadPoolExecutor

def fetch(url):
    time.sleep(2)
    return f"{url} done"

urls = [f"site{i}.com" for i in range(8)]

start = time.time()
with ThreadPoolExecutor(max_workers=8) as executor:
    results = list(executor.map(fetch, urls))
print("took %.1fs" % (time.time() - start))   # ~2s, not ~16s

چون هر ترد بیشترِ وقت منتظر شبکه است و ۸ کارگر داریم، هر هشت دانلود عملاً هم‌زمان پیش می‌روند و کل کار حدود ۲ ثانیه (به‌جای ۱۶ ثانیه) طول می‌کشد.

پاسخ تمرین ۸

برای کارهای I/O-bound (شبکه، فایل، دیتابیس) از ThreadPoolExecutor و برای کارهای CPU-bound (محاسبات سنگین) از ProcessPoolExecutor استفاده کنید. تردها برای CPU-bound مناسب نیستند چون GIL اجازه‌ی اجرای موازیِ واقعیِ کدِ پایتون را نمی‌دهد؛ پس چند ترد در محاسبات سنگین سریع‌تر از یک ترد نمی‌شوند و باید از پردازه‌ها (که هرکدام GIL مستقل دارند) استفاده کرد.

Please login to bookmark Close
نظرات

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

فهرست مطالب

سرفصل دوره

تمرین

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

پاسخ تمرین ها

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

اشتراک گذاری

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

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

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

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

تنظیمات

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