Go, yüksek verimli ağ ve paralel programlar yazmak amacıyla tasarlandığından, yerleşik zamanlayıcıya (scheduler) ve goroutine'lerle basit paralellik yönetimine özel önem verilmiştir. Çoğu dillerde, işletim sistemi (OS) thread'leri doğrudan dil kullanıcıları tarafından yönetilirken, Go'da goroutine'ler daha hafif olup, sabit sayıda sistem thread'i üzerinde binlerce goroutine eş zamanlı çalışabilir.
Sorun: Doğrudan thread yönetimi zordur: bu, hızlı kaynak tüketimi, veri yarışları (data races) ve bellek yönetimi zorluklarına yol açar.
Çözüm: Go, M:N modelini kullanarak, büyük bir goroutine sayısını (M) sınırlı sayıda OS thread'i (N) üzerinde çoklamak için bir zamanlayıcı kullanır. Bu, Go runtime'ının düzeyinde uygulanmış olup, goroutine'lerin çalışmasını otomatik olarak dengeleyip yeniden dağıtır. Programcı sadece goroutine'lerin başlatılması ve senkronizasyonuyla ilgilenir, doğrudan OS thread'leriyle değil.
Kod Örneği:
package main import ( "fmt" "time" ) func worker(id int) { fmt.Printf("Worker %d başlatılıyor ", id) time.Sleep(time.Second) fmt.Printf("Worker %d tamamlandı ", id) } func main() { for i := 0; i < 5; i++ { go worker(i) } time.Sleep(2 * time.Second) }
Anahtar Özellikler:
Her goroutine ayrı bir işlemci çekirdeğinde eş zamanlı olarak çalışacak mı?
Hayır. Goroutine'ler çoklanır ve zamanlayıcı, eş zamanlı olarak gerçekleştirilen görevlerin gerçek sayısını belirler.
Belirli goroutine'lerin/thread'lerin yürütmesini manuel olarak yönetmek mümkün mü?
Hayır. Go runtime, doğrudan zamanlama için bir arayüz sağlamaz. Tek istisna, OS thread'lerinin sayısını belirten GOMAXPROCS'dir.
Büyük bir goroutine sayısı, programın otomatik olarak hızlanacağı anlamına mı gelir?
Hayır. Yüksek sayıda eş zamanlı işlem, ek yükler (overhead) yaratabilir: bağlam değiştirmeleri, kaynaklar için rekabet, GC sürelerinin uzaması ve bellek tüketiminin artışı.
Mikroservis, gelen istekleri paralel olarak işliyordu, goroutine sayısını sınırlamıyor ve WaitGroup ile bekleme yapmıyordu — sonuç: artan yanıt süresi, data races, öngörülemeyen zaman aşımı.
Artılar:
Eksiler:
İşçi yöneticisi, goroutine havuzu aracılığıyla gerçekleştirilir, aynı anda çalışan görev sayısı, bir semafor veya kanallar aracılığıyla sınırlanır. WaitGroup, tüm görevlerin tamamlanmasını doğru bir şekilde bekler.
Artılar:
Eksiler: