Sobes.tech
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:

  1. Planlayıcı (Go'nun çalışma zamanı parçası), yeni goroutine'leri P'nin küresel veya yerel kuyruklarına yerleştirir.
  2. P ile ilişkili bir M, P'nin kuyruğundan bir goroutine alır ve yürütür.
  3. 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.
  4. 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
}