پاسخ تمرین ۱
set(): پرچم راTrueمیکند و همهی تردهای منتظر را آزاد میکند.clear(): پرچم را دوبارهFalseمیکند.wait(timeout=None): تاTrueشدن پرچم متوقف میشود؛ اگر از قبلTrueباشد بیدرنگ رد میشود. باtimeoutمقدارTrue/Falseبرمیگرداند.is_set(): بدون توقف، وضعیت فعلی پرچم را برمیگرداند.- مقدار اولیهی پرچم
Falseاست.
پاسخ تمرین ۲
Event یک سیگنال «چسبنده» است؛ وقتی set() شود پرچم True میماند. پس اگر بدون clear() دوباره به wait() برسیم، چون پرچم هنوز True است بدون توقف رد میشود و ترد اصلاً منتظر نمیماند. با clear() پرچم را پایین میآوریم تا wait() بعدی واقعاً منتظر بماند.
پاسخ تمرین ۳
import time
from threading import Thread, Event
start_signal = Event()
def worker(worker_id):
print(f"worker {worker_id} is ready")
start_signal.wait()
print(f"worker {worker_id} is running")
for i in range(1, 4):
Thread(target=worker, args=(i,)).start()
time.sleep(2)
print("GO!")
start_signal.set()پاسخ تمرین ۴
from threading import Thread, Event
event = Event()
def worker():
if event.wait(timeout=2):
print("signal received")
else:
print("timed out")
Thread(target=worker).start()
# never call event.set() -> prints "timed out" after 2 secondsپاسخ تمرین ۵
تله این است که clear() فقط روی تردهایی اثر میگذارد که بعداً wait() میکنند و تردهای همزمانآزادشده را تحت تأثیر قرار نمیدهد. اگر چند ترد یک Event مشترک داشته باشند و یکی بلافاصله بعد از بیدارشدن clear() کند، تردی که بعداً روی همان Event خاموش wait() کند ممکن است برای همیشه منتظر بماند (Deadlock). راه امنتر: برای هر مرحله یک Event جداگانه بسازید تا نیازی به clear() نباشد.
پاسخ تمرین ۶
import time
from threading import Thread, Event
stop_event = Event()
def background():
while not stop_event.is_set():
print("working...")
stop_event.wait(timeout=1) # wakes up immediately when set() is called
print("stopped cleanly")
t = Thread(target=background)
t.start()
time.sleep(3)
stop_event.set()
t.join()پاسخ تمرین ۷ (فشردهسازی پس از دانلود)
compress_file با event.wait() منتظر سیگنال میماند و download_file پس از پایان دانلود با event.set() سیگنال را میفرستد؛ به این ترتیب فشردهسازی حتماً بعد از دانلود اجرا میشود:
from time import sleep
from threading import Event, Thread
def download_file(event):
print('starting download')
sleep(3)
print('download completed')
event.set() # signal that the download is done
def compress_file(event):
event.wait() # wait until the download finishes
print('starting compression')
sleep(2)
print('compression completed')
if __name__ == '__main__':
event = Event()
Thread(target=download_file, args=(event,)).start()
Thread(target=compress_file, args=(event,)).start()