7. Eşzamanlılık — birlikte, baslat, kanal
Aynı anda birden çok iş yapmak. KabaLang'in modeli yapılandırılmış eşzamanlılıktır: görevler bir kapsamda doğar ve o kapsam bitmeden hepsi biter. Böylece "arka planda unutulmuş görev" diye bir şey olmaz.
birlikte: + baslat
fonksiyon is_yap(ad):
yazdir("çalışıyor: " + ad)
birlikte:
baslat is_yap("a")
baslat is_yap("b")
baslat is_yap("c")
yazdir("hepsi bitti")birlikte: bloğu, içindeki bütün görevler bitmeden bir sonraki satıra
geçmez. Yukarıdaki programda hepsi bitti her zaman en sonda yazılır.
Görevden değer almak — baslat + bekle()
fonksiyon kare(x):
don x * x
birlikte:
a = baslat kare(6)
b = baslat kare(7)
dogrula(a.bekle() == 36, "a")
dogrula(b.bekle() == 49, "b")
yazdir("görev değerleri tamam")⚠️ g = baslat f() yalnız bir birlikte: bloğunun içinde yazılabilir.
Blok dışında yazarsanız derleyici hata[KAPSAMSIZ_BASLAT] verir
(kabalang acikla KAPSAMSIZ_BASLAT) — çünkü görev tutamacı kapsamın
kendisine bağlıdır:
fonksiyon kare(x):
don x * x
g = baslat kare(6)
yazdir(metin(g.bekle()))arkada_calistir: — kapsamsız arka plan işi
Beklemek istemediğiniz kısa işler için:
kullan kaba.sistem
fonksiyon selam():
yazdir("arka planda")
arkada_calistir:
selam()
uyu(300) # işin görünmesi için bekliyoruz
yazdir("ana akış sürdü")⚠️ arkada_calistir yerel değişken YAKALAYAMAZ. Yakalarsa derleme
KACAK_YAKALAMA ile durur — uyarı değil, hata. Sebep: yerel değişken
görev bitmeden yok olabilir; bu, sessiz bir bellek hatası olurdu.
fonksiyon f():
v = "yerel"
arkada_calistir:
yazdir(v)
f()Derleyicinin önerdiği çözüm gerçekten çalışır — görevi birlikte: kapsamına
alın; kapsam bitmeden görev biteceği için yakalama güvenlidir:
fonksiyon f():
v = "yerel"
birlikte:
baslat yazdir(v)
f()
yazdir("güvenli yakalama")kanal<T> — görevler arası veri
Kanal, bir görevin ürettiğini başka bir görevin tüketmesini sağlar. Kilit yazmanız gerekmez.
fonksiyon uret(kn):
dongu i icinde 1..5:
kn.gonder(i)
kn.kapat() # ⚠️ kapatmazsanız tüketici sonsuza kadar bekler
fonksiyon tuket(kn):
toplam = 0
iken dogru:
v = kn.al()
eger v.bos_mu(): # kanal kapandı
kir
toplam = toplam + v.deger()
dogrula(toplam == 15, "1..5 toplamı")
yazdir(f"toplam: {toplam}")
k: kanal<sayi> = kanal(2) # 2 elemanlık tampon
birlikte:
baslat uret(k)
baslat tuket(k)
yazdir("kanal tamam")| Yazım | Anlamı |
|---|---|
kanal(n) |
n elemanlık sınırlı tampon; dolunca gönderen bekler (geri basınç) |
kanal(0) |
randevu: gönderen, alıcı teslim alana kadar bekler |
kn.gonder(v) |
veri koy |
kn.al() |
veri al — belki<T> döner; bos kanalın kapandığını gösterir |
kn.kapat() |
artık veri gelmeyecek |
Randevu (tamponsuz) kanal:
fonksiyon uret(kn):
dongu i icinde 1..3:
kn.gonder(i)
kn.kapat()
fonksiyon tuket(kn):
toplam = 0
iken dogru:
v = kn.al()
eger v.bos_mu():
kir
toplam = toplam + v.deger()
dogrula(toplam == 6, "randevu kanalı")
k: kanal<sayi> = kanal(0)
birlikte:
baslat uret(k)
baslat tuket(k)
yazdir("randevu tamam")Birden çok üretici tek kanala yazabilir; hepsi bitmeden kanalı kapatan ayrı bir görev kullanılır:
kullan kaba.sistem
fonksiyon uret(kn, bas):
dongu i icinde 1..3:
kn.gonder(bas + i)
fonksiyon kapatici(kn):
uyu(300)
kn.kapat()
fonksiyon tuket(kn):
toplam = 0
iken dogru:
v = kn.al()
eger v.bos_mu():
kir
toplam = toplam + v.deger()
dogrula(toplam == 42, f"1+2+3 + 11+12+13 = 42 bekleniyordu")
yazdir(f"toplam: {toplam}")
k: kanal<sayi> = kanal(8)
birlikte:
baslat uret(k, 0)
baslat uret(k, 10)
baslat tuket(k)
baslat kapatici(k)
yazdir("çok üretici tamam")Uyumak: uyu(ms)
kullan kaba.sistem
uyu(200) # 200 milisaniye
yazdir("uyandım")⚠️ bekle adı görev beklemek için ayrılmıştır (g.bekle()); uyku
için uyu(ms) yazın. Servis yazıyorsanız uyu() bile yanlış seçimdir:
servis.uyu(ms) sinyal gelince anında uyanır
(11. sayfa).
yazdir iş parçacığı güvenlidir
Birden çok görev aynı anda yazdir çağırabilir; satırlar iç içe geçmez.
(Bu ölçülmüş bir kusurdu: düz cout kullanımıyla beş koşunun üçünde
satırlar birbirine karışıyordu.)
Bugün olmayan
asyncanahtar sözcüğü rezerve edilmiştir ama uygulanmamıştır. Yazarsanız "henüz uygulanmadı" yanıtı alırsınız; eşzamanlılık bugünbirlikte/baslat/kanalüzerinden yazılır.- Paylaşılan bir değişkeni iki görevden aynı anda yazmak yarış koşuludur;
dil bunu bugün engellemez. Veri paylaşımını
kanalile yapın.