8.7. Olaylar¶
asyncio.Event, modülün sağladığı en basit sinyalleme ilkelidir. Bir eşyordam, bir şey olduğunda bir olayı ayarlar; başka herhangi bir sayıda eşyordam, devam etmeden önce olayın ayarlanmasını bekler. Yük yoktur – bir olay, açılan ve bir şey onu temizleyene kadar açık kalan bir boole değeridir.
8.7.1. Temel biçim¶
import asyncio
async def waiter(evt):
print("waiting")
await evt.wait()
print("got signal")
async def main():
evt = asyncio.Event()
asyncio.create_task(waiter(evt))
await asyncio.sleep(1)
evt.set()
await asyncio.sleep(0)
asyncio.run(main())
Bekleyen görev çalışır, await evt.wait()‘e ulaşır ve askıya alınır – olay temizlenmiş durumda başlar, bu yüzden wait çağrısı kontrolü döngüye geri verir. Bir saniye sonra main, evt.set() çağırır ve bekleyenin devam etmesi zamanlanır. Sondaki await asyncio.sleep(0) yalnızca bir yield’dir, böylece döngü main dönmeden önce bekleyeni çalıştırma şansı bulur.
8.7.2. Dört metot¶
set()– olayı ayarlanmış duruma getirir ve o andawait()üzerinde engellenmiş her eşyordamın devam etmesini zamanlar. Olay, temizlenene kadar ayarlanmış kalır.clear()– olayı yeniden temizlenmiş duruma getirir. Daha sonraawait wait()yapan eşyordamlar tekrar engellenir.wait()– bir eşyordam. Olay zaten ayarlanmışsa hemen geri döner. Aksi takdirde bir şey onu ayarlayana kadar engeller.is_set()– engellemeden mevcut durumu döndürür. Bir eşyordamın olayı beklemeden kontrol etmek istediği durumlarda kullanışlıdır.
8.7.3. Birden fazla bekleyen¶
Birkaç eşyordam aynı olayı await edebilir. Bir şey set() çağırdığında bunların hepsinin devam etmesi zamanlanır. Olay varsayılan olarak birden çoğa çalışır; birkaç bekleyene dağıtmak için birkaç olaya gerek yoktur.
8.7.4. Bir olayı yeniden kullanma¶
Yaygın bir kalıp, bir olayı tekrar tekrar kullanmaktır – sinyal başına bir kez çalışan bir eşyordam – her geçişten sonra onu temizleyerek:
async def worker(go):
while True:
await go.wait()
do_one_unit_of_work()
go.clear()
Üretici, iş olduğunda olayı ayarlar; çalışan, sinyali aldıktan sonra onu temizler. Üretici, çalışan uyanmadan önce olayı tekrar ayarlayabiliyorsa, çalışan temizlemeden önce bu durumu ele almak isteyebilir (while go.is_set(): ...).
8.7.5. Güvenli bağlamlar¶
Event üzerinde bir kesme işleyicisinin içinden set() çağırmak güvenli değildir. Bekleyenleri zamanlamak için kullandığı mekanizma, kesmelerin olmadığı olay döngüsünün kendi bağlamı içinde çalıştığını varsayar. Bir asyncio görevini bir kesme işleyicisinden uyandırmak için doğru ilkel ThreadSafeFlag‘tir (kısa süre içinde ele alınacak).