Middle+
Go dilinde eşzamanlılık yönetimi (GMP) deseninden bahsedin.
sobes.tech yapay zeka
AI'dan gelen yanıt
GMP, Go dilinde goroutine'lerin yürütülmesini planlama modeli olup:
- G (Goroutine): Hafif ağırlıklı yürütme akışı, sistem akışları üzerinde soyutlama.
- M (Machine): İşletim sisteminin bir akışı. Bir veya birkaç goroutine'un kodunu çalıştırabilir.
- P (Processor): Mantıksal işlemci, goroutine'lerin yürütülmesi için bağlamı temsil eder. Her P'ye bir M atanır ve P, runnable durumundaki goroutine'lerin yerel bir kuyruğunu içerir. Varsayılan P sayısı
$GOMAXPROCS(genellikle işlemci çekirdeği sayısıdır).
Çalışma şekli:
- Planlayıcı (Go'nun çalışma zamanı parçası), yeni goroutine'leri P'nin küresel veya yerel kuyruklarına yerleştirir.
- P ile ilişkili bir M, P'nin kuyruğundan bir goroutine alır ve yürütür.
- Bir goroutine engellendiğinde (örneğin, I/O beklerken veya bir mutex'te):
- M, mevcut P'den ayrılır.
- Planlayıcı, bu P'yi alacak başka bir M bulmaya çalışır veya yeni bir M oluşturur.
- Engellenen goroutine, özel bir kuyruğa konur.
- Engelleme kaldırıldığında, goroutine tekrar runnable olur ve P'nin kuyruğuna geri döner.
- Goroutine, zaman dilimini tükettiğinde veya açıkça kontrolü devrettiğinde (nadiren), planlayıcı M'yi aynı P'deki başka bir goroutine'a geçirebilir.
Bu yaklaşımın avantajları:
- Sistem akışlarının M verimli kullanımı.
- Doğal akışlara kıyasla bağlam değiştirme maliyetlerinin azaltılması.
- "Work stealing" mekanizmasıyla P arasında yük dengeleme (M, başka bir P'nin kuyruğundan goroutine çalabilir).
Goroutine oluşturma örneği:
// main.go
package main
import (
"fmt"
"time"
)
func worker(id int) {
fmt.Printf("İşçi %d başlıyor\n", id)
time.Sleep(time.Second) // Bloklama/doluluk örneği
fmt.Printf("İşçi %d tamamlandı\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
go worker(i) // Yeni bir goroutine oluştur
}
time.Sleep(time.Second * 2) // Goroutine'lerin bitmesini bekle
}