این تمرینها بر پایهی درس کلاس Semaphore و BoundedSemaphore هستند.
تمرین ۱ (مفهومی)
تفاوت اصلی Semaphore و Lock چیست؟ Semaphore(1) از نظر رفتاری معادل چه چیزی است؟
تمرین ۲ (مفهومی)
وقتی Semaphore(2) میسازیم، هر بار acquire() و release() چه اثری روی شمارنده دارد؟ اگر شمارنده صفر شود و تردی acquire() کند چه میشود؟
تمرین ۳ (مفهومی)
اگر بهاشتباه تعداد release() بیشتر از acquire() شود، چه اتفاقی برای Semaphore میافتد؟ BoundedSemaphore چطور این مشکل را آشکار میکند؟
تمرین ۴ (کد)
برنامهای بنویسید که ۵ ترد بسازد اما با Semaphore و دستور with تضمین کند در هر لحظه حداکثر ۲ ترد به بخش بحرانی وارد میشوند.
تمرین ۵ (کد)
با acquire(timeout=...) کاری کنید اگر تردی نتوانست در ۱ ثانیه یک جا بگیرد، بهجای انتظار، پیام «skipped» چاپ کند و خارج شود.
تمرین ۶ (کد — بهینهسازی دانلودر)
تکهکد زیر لیستی از آدرس فایلها را میگیرد و دانلود میکند. برای افزایش سرعت، آن را با مولتیتردینگ بازنویسی کنید؛ اما برای اینکه سرور شما را بلاک نکند، اجازه ندهید بیش از ۵ ترد در یک لحظه فعال باشد.
import requests
import os
file_urls = [f"https://dummyimage.com/{i}.png" for i in range(300, 400)]
def download_file(file_url, cookies, headers):
file_name = os.path.basename(file_url)
file_path = os.path.join("downloads", file_name)
print(f"Downloading {file_name}...")
response = requests.get(file_url, cookies=cookies, headers=headers)
with open(file_path, 'wb') as f:
f.write(response.content)
print(f"{file_name} downloaded successfully.")
if not os.path.exists("downloads"):
os.makedirs("downloads")
for file_url in file_urls:
download_file(file_url, {}, {})
print("All files downloaded successfully.")