0Pricing
Go Academy · Ders

Tamponlu Kanallar

Kapasite, kanalları kapatma ve kanal üzerinde range

Tamponlu Kanallar, CoddyKit'te ücretsiz bir Go Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Go Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Go Academy kursu toplamda 4 dersten oluşur.

Arabellekli Kanal Nedir?

Arabellekli kanalın bir kapasitesi vardır — arabellekte yer olduğu sürece gönderimler engellenmez. Kanal bir kuyruk gibi davranır:

package main
import "fmt"

func main() {
    ch := make(chan int, 3)  // capacity 3

    ch <- 1  // does not block — buffer has room
    ch <- 2  // does not block
    ch <- 3  // does not block
    // ch <- 4  // would block — buffer full

    fmt.Println(<-ch) // 1
    fmt.Println(<-ch) // 2
    fmt.Println(<-ch) // 3
}

Kuyruk Olarak Arabellekli Kanal

Arabellekli kanallar, goroutine'ler arasında bir FIFO kuyruğu uygular:

package main
import ("fmt"; "sync")

func producer(ch chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 1; i <= 5; i++ {
        ch <- i
        fmt.Printf("produced %d\n", i)
    }
}

func main() {
    ch := make(chan int, 2)  // buffer 2 — producer runs ahead
    var wg sync.WaitGroup
    wg.Add(1)
    go producer(ch, &wg)
    wg.Wait()
    close(ch)
    for v := range ch { fmt.Printf("consumed %d\n", v) }
}

Kanallarda len() ve cap()

Arabellekli bir kanalın geçerli boyutunu ve kapasitesini inceleyin:

package main
import "fmt"

func main() {
    ch := make(chan string, 5)
    ch <- "a"
    ch <- "b"
    ch <- "c"

    fmt.Println("cap:", cap(ch))  // 5
    fmt.Println("len:", len(ch))  // 3 — items currently buffered

    <-ch
    fmt.Println("len:", len(ch))  // 2
}

Üretici ve Tüketiciyi Birbirinden Ayırma

Bir arabellek, üreticinin hızını tüketicininkinden ayırır. Üretici, engellenmeden önce arabellek boyutu kadar ilerleyebilir:

package main
import ("fmt"; "sync"; "time")

func produce(ch chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        ch <- i
    }
}

func consume(ch <-chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for v := range ch {
        time.Sleep(10 * time.Millisecond)  // slower consumer
        fmt.Println("consumed:", v)
    }
}

func main() {
    ch := make(chan int, 3)
    var wg sync.WaitGroup
    wg.Add(2)
    go produce(ch, &wg)
    go consume(ch, &wg) // BUG: produce closes before consume sees all
    // In practice, coordinate close carefully
    fmt.Println("decoupled")
}

Arabellekli Kanalla Semafor

Kapasitesi N olan arabellekli bir kanal, eşzamanlı goroutine sayısını N ile sınırlandırabilir — basit bir semafor:

package main
import ("fmt"; "sync"; "time")

func main() {
    sem := make(chan struct{}, 3)  // max 3 concurrent
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        i := i
        go func() {
            defer wg.Done()
            sem <- struct{}{}    // acquire
            defer func() { <-sem }()  // release
            fmt.Printf("job %d running\n", i)
            time.Sleep(50 * time.Millisecond)
        }()
    }
    wg.Wait()
}

Arabellekli Kanalı Kapatma

Arabellekli bir kanalı kapatmak, alıcıların kapanmayı algılamadan önce arabellekte kalan değerleri tüketmesine olanak tanır:

package main
import "fmt"

func main() {
    ch := make(chan int, 5)
    for i := 1; i <= 3; i++ { ch <- i }
    close(ch)

    // Drain all buffered values after close:
    for v := range ch {
        fmt.Println(v)  // 1, 2, 3
    }
    // range exits after channel closed and drained
}

Arabellekli ve Arabelleklenmemiş: Hangisi Ne Zaman Seçilmeli

Seçim rehberi:

  • Arabelleklenmemiş: garantili eşzamanlı aktarım, katı sıralama, buluşma eşzamanlaması
  • Arabellekli: üretici ve tüketici hızlarını birbirinden ayırma, engellenmeyi azaltma, semafor uygulama, N sonucu toplama
  • Varsayılan olarak arabelleklenmemiş kullanın — boyutunu gerekçelendirebildiğinizde arabellek ekleyin
  • Çok küçük arabellek boyutu → yine engellenir; çok büyük boyut → hataları gizler

Arabellekli Kanalla Sonuçları Toplama

Paralel goroutine'lerden gelen sonuçları engellenmeden toplamak için arabellekli bir kanal kullanın:

package main
import ("fmt"; "sync")

func square(n int) int { return n * n }

func main() {
    nums := []int{1, 2, 3, 4, 5}
    results := make(chan int, len(nums))  // buffer = goroutine count
    var wg sync.WaitGroup

    for _, n := range nums {
        wg.Add(1)
        n := n
        go func() {
            defer wg.Done()
            results <- square(n)
        }()
    }
    wg.Wait()
    close(results)

    for r := range results { fmt.Println(r) }
}

Dolu Arabellekle Goroutine Sızıntısı

Arabellek doluysa ve okuyucu yoksa gönderici sonsuza dek engellenir — bu bir goroutine sızıntısıdır:

package main
import ("fmt"; "time"; "runtime")

func main() {
    ch := make(chan int, 2)
    // Start goroutine that fills buffer and then blocks
    go func() {
        ch <- 1
        ch <- 2
        ch <- 3  // blocks: buffer full, no receiver
        fmt.Println("never reached")
    }()
    time.Sleep(50 * time.Millisecond)
    fmt.Println("goroutines:", runtime.NumGoroutine()) // 2 — leaked
}

Arabellekli Kanal Olarak time.After

time.After, kapasitesi 1 olan bir <-chan time.Time döndürür. Çalışma zamanı, süre dolduktan sonra kanala gönderim yapar; ardından kanal çöp toplayıcı tarafından toplanır:

package main
import ("fmt"; "time")

func doWithTimeout(work func() string) (string, bool) {
    result := make(chan string, 1)
    go func() { result <- work() }()
    select {
    case r := <-result:
        return r, true
    case <-time.After(100 * time.Millisecond):
        return "", false
    }
}

func main() {
    r, ok := doWithTimeout(func() string {
        time.Sleep(50 * time.Millisecond)
        return "done"
    })
    fmt.Println(r, ok)
}

Kısa Kontrol

Kapasitesi tamamen dolu olan arabellekli bir kanala gönderim yaptığınızda ne olur?

Özet: Arabellekli Kanallar

Özet:

  • make(chan T, N), kapasitesi N olan arabellekli bir kanal oluşturur
  • Gönderimler yalnızca arabellek doluyken; alma işlemleri yalnızca arabellek boşken engellenir
  • len(ch) — geçerli öğe sayısı; cap(ch) — kapasite
  • Üreticileri ve tüketicileri birbirinden ayırmak, paralel sonuçları toplamak ve semafor uygulamak için kullanın
  • Kapatma, EOF'dan önce arabelleğin boşaltılmasına olanak tanır; range ch bunu otomatik olarak yönetir

Sıkça Sorulan Sorular

“Tamponlu Kanallar” dersi ücretsiz mi?

Evet — “Tamponlu Kanallar” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Go Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Go Academy kursu toplamda 4 dersten oluşur.

“Tamponlu Kanallar” dersinde ne öğreneceğim?

Kapasite, kanalları kapatma ve kanal üzerinde range Go Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Go Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Go Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.

“Tamponlu Kanallar” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Go Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Go Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Goroutine Başlatma
  2. Tamponsuz Kanallar
  3. Tamponlu Kanallar
  4. Kanal Yönü ve Pipeline Örüntüleri
← Go Academy Sayfasına Dön