Preemption
- Go kursu
- Uzman
- Ders 4/34
- 4 dk
Go scheduler'ın goroutine'leri zorla durdurmasını öğrenirsin.
Preemption
Bir goroutine P'yi çok uzun tutarsa diğerleri aç kalır. Go 1.14'ten beri zamanlayıcı asenkron preemption kullanır: sysmon adlı izleyici, 10 ms'den uzun çalışan goroutine'in iş parçacığına sinyal gönderir ve onu güvenli bir noktada durdurur.
go func() {
for {} // Go 1.14 öncesi P'yi sonsuza dek tutabilirdi
}()Eskiden durdurma yalnızca fonksiyon çağrılarında yapılabiliyordu; sıkı döngüler tüm programı kilitleyebiliyordu.
İşbirlikçi noktalar
Preemption'ın yanında goroutine'ler kendiliğinden de P'yi bırakır: kanal işlemleri, kilitler, time.Sleep, ağ G/Ç ve runtime.Gosched(). Ayrıca her fonksiyon girişindeki yığın büyüme denetimi bir durdurma noktası işlevi görür. Bu yüzden gerçek programlarda goroutine'ler sık sık el değiştirir.
Uygulama Sıkı döngü yanında çalışma
runtime.GOMAXPROCS(1) ayarla. Bir goroutine'de for {} sonsuz döngüsü başlat. Ardından time.Sleep(20 * time.Millisecond) çağır ve fmt.Println("main devam etti") yazdır. Preemption sayesinde program kilitlenmez.
Başlangıç kodu
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
// buraya yaz
}Örnek çözüm
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(1)
go func() {
for {
}
}()
time.Sleep(20 * time.Millisecond)
fmt.Println("main devam etti")
}Beklenen çıktı
main devam etti
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Asenkron preemption hangi mekanizmayla tetiklenir?
- GC'nin bitmesi
- Kanal kapanması
- sysmon'un iş parçacığına gönderdiği sinyal Doğru cevap
- Fonksiyon çağrısındaki yığın kontrolü
Açıklama: Unix'te SIGURG kullanılır; sinyal işleyici goroutine'in bağlamını kaydedip zamanlayıcıya döner.
2 Süre eşiği
const forcePreemptNS = ____ * 1000 * 1000
const forcePreemptNS = 10 * 1000 * 1000
Açıklama: Go zamanlayıcısının zaman dilimi yaklaşık 10 ms'dir.
3 Bırakma yolu
| Kavram | Anlamı |
|---|---|
Kanal bekleme |
İşbirlikçi |
runtime.Gosched |
Gönüllü bırakma |
Sinyal (SIGURG) |
Asenkron preemption |
Fonksiyon girişi |
Yığın kontrolü noktası |