CodeBlanks Logo Icon CodeBlanks

Preemption

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

main.go
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
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

Soru
const forcePreemptNS = ____ * 1000 * 1000
Cevap
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ı

Uzman bölümündeki tüm dersler