Concurrency Patterns: Fan-Out/Fan-In Deseni Adım Adım

Bir işi birden fazla goroutine'e dağıtıp (fan-out), sonuçları toplamak (fan-in) için kullanılan desendir. Örneğin 10 farklı API'ye istek atıp hepsinin cevabını beklemek gibi.

Fan-out: Bir channel'dan veri oku, birden fazla goroutine'e gönder.
Fan-in: Birden fazla channel'dan veri oku, tek bir channel'a yaz.

Sayılar listesini 3 goroutine'e dağıtıp, karelerini hesaplayalım:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1package main
2
3import (
4"fmt"
5"sync"
6)
7
8func main() {
9sayilar:= []int{1, 2, 3, 4, 5, 6}
10
11// Fan-Out: Sayıları 3 worker'a dağıt
12workers:= 3
13girisChan:= make(chan int)
14
15// Fan-In: Sonuçları topla
16sonucChan:= make(chan int)
17var wg sync.WaitGroup
18
19// Worker'ları başlat
20for i:= 0; i < workers; i++ {
21wg.Add(1)
22go worker(girisChan, sonucChan, &wg)
23}
24
25// Sayıları gönder (ayrı goroutine'de)
26go func() {
27for _, sayi:= range sayilar {
28girisChan <- sayi
29}
30close(girisChan)
31}()
32
33// Sonuçları oku
34go func() {
35wg.Wait()
36close(sonucChan)
37}()
38
39for sonuc:= range sonucChan {
40fmt.Println("Kare:", sonuc)
41}
42}
43
44func worker(girisChan <-chan int, sonucChan chan<- int, wg *sync.WaitGroup) {
45defer wg.Done()
46for sayi:= range girisChan {
47sonucChan <- sayi * sayi
48}
49}

Çıktı:

1Kare: 1
2Kare: 4
3Kare: 9
4Kare: 16
5Kare: 25
6Kare: 36
  1. Fan-Out: girisChan açılır, 3 worker goroutine başlatılır
  2. Dağıtım: Sayılar sırayla channel'a yazılır
  3. İşleme: Her worker kendi hızında sayıyı alıp karesi hesaplar
  4. Fan-In: WaitGroup tüm worker'ları bekler, sonra sonucChan kapatılır
  5. Okuma: Main goroutine sonuçları channel'dan okur
  • Ağır işleri paralel yap
  • Kaynakları verimli kullan
  • Bekleme sürelerini azalt
  • Ölçeklenebilir kod yaz

Bu desen API çağrıları, dosya işleme, veri analizi gibi yerlerde hayat kurtarır. (Go'da Eş Zamanlılık Desenleri: Worker Pool Uygulaması)

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz

5 yorum

  • adlı kullanıcıya yanıt verdi
    voltyra
    @voltyra

    aynen gönderen `chan < ` ile yazıyor alan `< chan` ile okuyor fan out kısmında 3 workerı

  • adlı kullanıcıya yanıt verdi
    terslale

    Tamam o zaman alan taraf da `< ` operatörüyle channeldan okuyor yani Yani gönderen `chan

  • adlı kullanıcıya yanıt verdi
    voltyra
    @voltyra

    Bir tarafta veri gönderen var diğer tarafta alan var Gönderen goroutine channela yazıyor

  • adlı kullanıcıya yanıt verdi
    terslale

    channelı nasıl kullanmak lazım tam anlamadım hangi tarafta veri yazıyorsun hangi tarafta

  • voltyra
    @voltyra

    Ya bu pattern aslında çok pratik özellikle APIlerden paralel veri çekerken Ama channelı