Sonuç toplama
- Go kursu
- Orta seviye
- Ders 27/80
- 6 dk
Sonuçları ayrı bir channel'dan toplarsın.
Sonuçları toplamak
Sonuç sayısı her zaman bilinmez. Daha sağlam yol: işçileri sync.WaitGroup ile izlemek ve hepsi bitince sonuç kanalını kapatmak. Böylece toplayan taraf range kullanabilir:
var wg sync.WaitGroup
for w := 0; w < n; w++ {
wg.Add(1)
go func() { defer wg.Done(); isci(isler, sonuclar) }()
}
go func() { wg.Wait(); close(sonuclar) }()
for s := range sonuclar { ... }Sıra ve eşleme
Eşzamanlı işçilerden sonuçlar rastgele sırayla gelir. Girdi sırası önemliyse ya sonucu iş kimliğiyle birlikte gönderip bir dilimde o kimliğin yerine yazarsın ya da sonuçları sonradan sıralarsın:
out := make([]int64, len(dosyalar))
for s := range sonuclar {
out[s.IsID] = s.Boyut
}Uygulama Sıralı toplama
Dört işin (ID 0–3) her biri ID * 10 değerini üretsin. İki işçi kullan, WaitGroup ile bitişi izle, sonuç kanalını kapat ve sonuçları ID sırasına göre bir dilime yaz. Dilimi yazdır.
Başlangıç kodu
package main
import (
"fmt"
"sync"
)
func main() {
// buraya yaz
}Örnek çözüm
package main
import (
"fmt"
"sync"
)
type Sonuc struct{ ID, Deger int }
func main() {
isler := make(chan int)
sonuclar := make(chan Sonuc)
var wg sync.WaitGroup
for w := 0; w < 2; w++ {
wg.Add(1)
go func() {
defer wg.Done()
for id := range isler {
sonuclar <- Sonuc{id, id * 10}
}
}()
}
go func() {
for i := 0; i < 4; i++ {
isler <- i
}
close(isler)
}()
go func() {
wg.Wait()
close(sonuclar)
}()
out := make([]int, 4)
for s := range sonuclar {
out[s.ID] = s.Deger
}
fmt.Println(out)
}Beklenen çıktı
[0 10 20 30]
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 <code>wg.Add(1)</code> neden goroutine'in <strong>içinde</strong> değil, önünde çağrılır?
- Done'u otomatik çağırsın diye
- Wait, Add'den önce çalışıp erken dönmesin diye Doğru cevap
- Daha kısa olduğu için
- Add goroutine içinde çalışmaz
Açıklama: Goroutine henüz başlamadan Wait çalışırsa sayaç sıfır görünür ve Wait hemen döner; Add önceden yapılmalıdır.
2 Hepsini bekle
go func() {
wg.____()
close(sonuclar)
}()
go func() {
wg.Wait()
close(sonuclar)
}()
Açıklama: Wait tüm işçiler Done çağırana kadar bekler; sonra sonuç kanalı güvenle kapanır.
3 Araç
| Kavram | Anlamı |
|---|---|
wg.Add(1) |
Goroutine'den önce |
defer wg.Done() |
İşçi bitince |
wg.Wait + close |
Sonuç kanalını kapat |
out[s.IsID] |
Girdi sırasını koru |