Bölüm 9 · Yazılımın içi · Ders 43
Olay döngüsü
Tek iş parçacığı, iki kuyruk: çıktı sırası neden şaşırtır?
Veri. Robotun denetleyicisi tek iş parçacıklı bir olay döngüsünde çalışıyor: 10 ms'de bir kontrol zamanlayıcısı, 5 ms'de gelen lidar verisi, bir de çözülen sözler (promise). Aynı anda yalnız bir iş yapabiliyor; yine de donmadan hepsine yetişmesi gerekiyor. Üç senaryoda çıktıların hangi sırayla ve hangi milisaniyede yazıldığını izliyoruz.
import asyncio, timeout, t0 = [], time.perf_counter()def log(s): # çıktı + zaman (ms)out.append(f"{s}@{(time.perf_counter()-t0)*1e3:.0f}ms")async def main():loop = asyncio.get_running_loop()log("başla") # eşzamanlıloop.call_later(0.010, log, "kontrol") # setTimeout 10 msloop.call_later(0.005, log, "lidar") # G/Ç 5 ms sonra hazırf = loop.create_future()f.add_done_callback(lambda _: log("söz")) # then()f.set_result(None) # söz çözüldüt = time.perf_counter()while time.perf_counter() - t < 0.06: # 60 ms hesappass # döngü kilitlilog("hesap bitti")await asyncio.sleep(0.02) # döngüye bırakasyncio.run(main()) # olay döngüsüprint(out)
Sahnedeki her sayı, aynı algoritmanın tarayıcında yapılan gerçek çalıştırmasından gelir (sabit tohum, her seferinde aynı sonuç). Python kodunu kendi bilgisayarında çalıştırırsan rastgele başlangıçlar farklı olacağı için sayılar biraz değişebilir.
Veri seti
Tüm veri setleri →Bu dersin kodu verisini kendi içinde üretir; indirilecek dosya yok. Kodu yine de aşağıda tarayıcında çalıştırabilirsin.
Kodu tarayıcıda çalıştırPython · NumPy · matplotlib · Pyodide
Python ve NumPy bu sayfada, tarayıcında çalışır (Pyodide). Kodu değiştirip yeniden çalıştırabilirsin; dersin veri setleri çalışma klasöründe hazır. Kod matplotlib kullanırsa grafikler çıktının altında görünür, yazdığı dosyalar (ör. egitim_gecmisi.csv) indirilebilir.
Çıktı
Çıktı burada görünecek.Nasıl çalışır
- Eşzamanlı kod çağrı yığınında sonuna kadar çalışır; araya hiçbir şey giremez.
- Yığın boşalınca önce mikro görev kuyruğunun TAMAMI işlenir (promise.then; asyncio'da call_soon'un hazır kuyruğu). Mikro görevin eklediği mikro görev de hemen çalışır.
- Sonra makro kuyruktan yalnız BİR görev alınır (setTimeout, G/Ç tamamlanması), ardından yine bütün mikro görevler. Bu yüzden 0 ms zamanlayıcı bile sözden sonra gelir.
- Zamanlayıcının süresi bir söz değil, bir alt sınırdır: döngü 60 ms hesapla meşgulse 10 ms zamanlayıcı 50 ms gecikir.
- Şunu dene: senaryoyu 2 yap; kontrol zamanlayıcısının kırmızı gecikme çizgisine bak. Ağır hesabı ayrı bir iş parçacığına ya da parçalara bölmek bu yüzden gerekir.
Neden önemli
JavaScript (tarayıcı, Node.js), Python asyncio, ROS 2'nin tek iş parçacıklı yürütücüsü ve birçok gömülü denetleyici bu modelle çalışır. Robotikte kural basittir: döngüde uzun süren bir şey yapma; yoksa güvenlik zamanlayıcıları ve sensör geri çağırmaları gecikir, robot geç fren yapar.
ESOF 323, 11. hafta: robotlarda derin öğrenme →