CodeBlanks Logo Icon CodeBlanks

Meydan okuma 1 - Scheduler

Goroutine davranışını inceleyen bir izleme aracı yazarsın.

Meydan okuma: sınırlı paralellik

1000 işi işleyen bir program yazacaksın ama aynı anda en fazla GOMAXPROCS kadar iş çalışmalı. Sınırsız goroutine açmak zamanlayıcıyı ve belleği zorlar; sabit sayıda işçi ise CPU'yu tam kullanır.

isler := make(chan int)
sonuc := make(chan int)
for w := 0; w < runtime.GOMAXPROCS(0); w++ {
    go isci(isler, sonuc)
}

İşçiler for i := range isler ile iş alır; kanal kapanınca biterler.

Plan

1) wg.Add(n) ile n işçi başlat. 2) Bir goroutine 1..1000 sayılarını isler'e gönderip kanalı kapatsın. 3) Başka bir goroutine wg.Wait() sonrası close(sonuc) yapsın. 4) main for r := range sonuc ile toplasın. İşçi her sayının karesini göndersin; beklenen toplam 333.833.500.

Uygulama İşçi havuzu

Plana göre havuzu yaz ve kareler toplamını yazdır.

Başlangıç kodu

main.go
package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    isler := make(chan int)
    sonuc := make(chan int)
    n := runtime.GOMAXPROCS(0)
    var wg sync.WaitGroup
    wg.Add(n)
    for w := 0; w < n; w++ {
        go func() {
            defer wg.Done()
            for i := range isler {
                sonuc <- i * i
            }
        }()
    }
    go func() {
        for i := 1; i <= 1000; i++ {
            isler <- i
        }
        close(isler)
    }()
    go func() {
        wg.Wait()
        close(sonuc)
    }()
    toplam := 0
    for r := range sonuc {
        toplam += r
    }
    fmt.Println(toplam)
}

Beklenen çıktı

333833500

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Sonuç kanalını kim ve ne zaman kapatmalıdır?

  • main, işleri gönderir göndermez
  • Hiç kapatılmamalı
  • Tüm işçiler bitince (WaitGroup beklendikten sonra) ayrı bir goroutine Doğru cevap
  • Her işçi kendi işi bitince

Açıklama: Birden çok gönderici varken kanalı bir işçi kapatırsa diğerleri kapalı kanala yazıp panic üretir; kapatma tüm göndericiler bitince yapılır.

2 Sonuçları kapat

Soru
go func() {
    wg.____()
    close(sonuc)
}()
Cevap
go func() {
    wg.Wait()
    close(sonuc)
}()

Açıklama: wg.Wait tüm işçiler Done çağırana kadar bekler; ancak sonra sonuç kanalı güvenle kapatılır.

3 Parça ve görev

Kavram Anlamı
isler kanalı İş dağıtımı
GOMAXPROCS(0) işçi Paralellik sınırı
wg.Wait + close Güvenli kapanış
range sonuc Toplama

Uzman bölümündeki tüm dersler