8.3. Olay döngüsü¶
Olay döngüsü (event loop), asyncio’nun altında çalıştırdığı motordur. Programdaki her görevin bir listesini tutar, her birinden o görevin bir sonraki await noktasına kadar çalışmasını ister ve bir sonraki hazır göreve geçer. Hazır görev kalmadığında bekler – gerçek bekleme, CPU’yu aygıt yazılımının (firmware) başka şeyler çalıştırması ve güç tasarrufu sağlayan uykuların devreye girmesi için uygun hale getiren şeydir – ta ki bir görevin beklediği bir şey kullanılabilir hale gelene kadar; ardından o görevi devam ettirir. Sonsuza dek tekrarlanır.
Çoğu uygulama döngüyle hiçbir zaman doğrudan etkileşim kurmaz. Döngü, asyncio.run() çağrısının bir sonucudur; uygulama eşyordamları yazar, onları görev olarak zamanlar ve döngü gerisini halleder.
8.3.1. asyncio.run() aslında ne yapar¶
Tek bir çağrı:
asyncio.run(main())
döngünün uygulama adına yönettiği daha uzun bir dizinin kısaltmasıdır:
Henüz yoksa olay döngüsünü oluştur.
Sağlanan eşyordamı bir görevin içine sar ve onu döngünün üst düzey giriş noktası olarak zamanla.
Döngüyü çalıştır – hazır görevler arasında ilerle, hiçbiri hazır değilken bekle, await’leri tamamlandığında görevleri devam ettir – ta ki üst düzey görev dönene ya da bir istisna yükseltene kadar.
Uygulamanın oluşturduğu ve hâlâ çalışan tüm görevleri iptal et.
Üst düzey eşyordamın döndürdüğü şeyi döndür (ya da yükselttiği şeyi yeniden yükselt).
8.3.2. Program başına tek döngü¶
MicroPython’ın asyncio’sunda tek bir olay döngüsü vardır, hepsi bu. Yeni bir döngü oluşturmak yoktur ve bir döngüyü başka bir döngünün içine yerleştirmek yoktur. Döngü üzerinde zaten çalışan bir eşyordamın içinden asyncio.run() çağırmak bir hatadır; döngü zaten oradadır ve eşyordamın yalnızca başlatmak istediği şeyi await etmesi gerekir.
Pratikte kural, önceki sayfanın kapanış satırıyla aynıdır: program başına tam olarak bir asyncio.run() çağrısı vardır, en üstte, arkasında tek bir async def main() ile. Geri kalan her şey main‘in içinde yaşar.
8.3.3. Doğrudan döngü erişimi¶
Bir uygulamanın döngünün kendisine dokunması gereken nadir durumlar için – çoğunlukla tanılama ve istisna işleyicileri – asyncio.get_event_loop(), Loop nesnesini döndürür. Oradan uygulama özel bir istisna işleyicisi kurabilir, döngünün ne yaptığını inceleyebilir veya (çok nadiren) asyncio.create_task() yerine doğrudan create_task() çağırabilir (bunlar aynı işlemdir).
Loop sınıfının sunduğu tüm yöntemler – run_forever(), stop(), set_exception_handler() ve geri kalanı – bu bölümün ilerleyen kısımlarındaki döngü kontrolü sayfasında ele alınmaktadır. O zamana kadar, bir uygulamanın ihtiyaç duyduğu tek şey asyncio.run(main()) ifadesidir.