Bölüm 9 · Yazılımın içi · Ders 44
Kilitlenme ve yarış durumu
İki iş parçacığı, iki kilit: program neden bazen durur ya da yanlış sayar?
Veri. Robotta iki iş parçacığı aynı anda çalışıyor: motor sürücüsü (M) ve sensör okuyucusu (S). İkisi de ortak bir komut sayacını artırıyor ve ikisi de iki paylaşılan kaynağa dokunuyor: A = motor veri yolu, B = sensör tamponu. Hangi iş parçacığının ne zaman çalışacağına işletim sistemi karar verir; biz bu araya girme sırasını bir tohumla canlandırıyoruz.
import numpy as nprng = np.random.default_rng(3) # araya girme sırasıdef prog(a, b): # önce a, sonra b kilidibody = [("lock", a), ("lock", b), ("read",), ("write",)]return (body + [("unlock", b), ("unlock", a)]) * 3th = {"M": prog("A", "B"), "S": prog("B", "A")} # ters sıra!pc, owner, reg, counter = {"M": 0, "S": 0}, {}, {}, 0def ready(t): # çalışabilir mi?if pc[t] == len(th[t]): return Falseop = th[t][pc[t]]return op[0] != "lock" or owner.get(op[1]) in (None, t) # kilit boşsawhile run := [t for t in th if ready(t)]:t = run[rng.integers(len(run))] # zamanlayıcı seçerop = th[t][pc[t]]; pc[t] += 1if op[0] == "lock": owner[op[1]] = tif op[0] == "unlock": del owner[op[1]]if op[0] == "read": reg[t] = counter # okuif op[0] == "write": counter = reg[t] + 1 # yazif all(pc[t] == len(th[t]) for t in th):print("bitti, sayaç", counter)else:print("KİLİTLENME:", owner, "sayaç", counter) # herkes bekliyor
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
- Yarış: 'sayaç += 1' aslında iki adımdır: oku, sonra yaz. İkisi de 3 okur, ikisi de 4 yazar: bir artırma kaybolur. Hata yalnız bazı araya girme sıralarında olur; bu yüzden 'rastgele' bozulur.
- Kilitlenme: M önce A'yı, S önce B'yi alır. Sonra M B'yi, S A'yı bekler. Bekleme grafiğinde döngü oluşur (M → B → S → A → M): hata yok, istisna yok, program yalnızca ilerlemez.
- Düzeltme: herkes kilitleri aynı sırayla alır (önce A, sonra B); döngü oluşamaz. Sayaç için ise kilit ya da atomik işlem (tek adımda oku-artır-yaz) kullanılır.
- Şunu dene: senaryo 1’de tohumu değiştir; bazı tohumlarda iş biter, yaklaşık yarısında kilitlenir. Senaryo 0’da da bazı tohumlar 10’u bulur, bazıları bulamaz. Senaryo 2’de hiçbir tohum kilitlenmez ve sayaç her zaman 6’dır.
Neden önemli
Robot yazılımı doğası gereği eşzamanlıdır: ROS 2'nin çok iş parçacıklı yürütücüsü, sürücü iş parçacıkları, kesme (interrupt) işleyicileri ve RTOS görevleri. Bu hatalar testte nadiren görünür, sahada bir gün robotu dondurur. Sabit kilit sırası, kilitleri kısa tutmak, atomik sayaçlar ve kilitsiz kuyruklar en yaygın çözümlerdir.
ESOF 323, 11. hafta: robotlarda derin öğrenme →