CodeBlanks Logo Icon CodeBlanks

Sonuç toplama

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

main.go
package main

import (
    "fmt"
    "sync"
)

func main() {
    // buraya yaz
}

Örnek çözüm

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

Soru
go func() {
    wg.____()
    close(sonuclar)
}()
Cevap
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

Orta seviye bölümündeki tüm dersler