Kanal arabellek boyutu nedir?


86

Eşzamansız bir kanal oluşturmaya çalışıyorum ve http://golang.org/ref/spec#Making_slices_maps_and_channels'a bakıyorum .

c := make(chan int, 10)         // channel with a buffer size of 10

Arabellek boyutunun 10 olması ne anlama geliyor? Tampon boyutu özellikle neyi temsil ediyor / sınırlıyor?


Burada ve daha
Ivan Black

Ayrıca buraya bakın yararlı. Çok açık ve anlaşılması kolay :)
Ardi Nusawan

Yanıtlar:


161

Tampon boyutu, gönderme engellemesi olmadan kanala gönderilebilecek elemanların sayısıdır. Varsayılan olarak, bir kanalın arabellek boyutu 0'dır (bunu elde edersiniz make(chan int)). Bu, kanaldan başka bir gorutin alana kadar her gönderimin engelleneceği anlamına gelir. Tampon boyutu 1 olan bir kanal, blok gönderene kadar 1 öğeyi tutabilir, böylece

c := make(chan int, 1)
c <- 1 // doesn't block
c <- 2 // blocks until another goroutine receives from the channel

21
İyi cevap. Effective Go'nun kanallarda anlatılan "Eş Zamanlılık" başlıklı güzel bir bölümü var. Şiddetle tavsiye edilen: golang.org/doc/effective_go.html
Levi

Bununla uğraşıyorum ve make (chan int, 1) engellemeden önce 3 değerin kanalıma geçmesine izin veriyor (log.Printlns ile test ediyor) ve varsayılan, engellemeden önce 2'ye izin vermektir. Herhangi bir fikrin nedeni:
Mauricio

@Mauricio Kulağa oldukça garip geliyor. Sadece yerel olarak Go 1.8.3'ü ve ayrıca golang.org'daki "Try Go" işlevini kullanarak test ettim ve her iki durumda da hala cevabımda belgelendiği gibi davranıyor.
Lily Ballard

1
Cevabı takdir ediyorum, ancak aslında konsoluma veri yazdırmayı yanlış yorumluyordum. Tarif ettiğiniz gibi çalışıyor.
Mauricio

10

Aşağıdaki kod, arabelleğe alınmamış kanalın engellenmesini gösterir:

// to see the diff, change 0 to 1
c := make(chan struct{}, 0)
go func() {
    time.Sleep(2 * time.Second)
    <-c
}()
start := time.Now()
c <- struct{}{} // block, if channel size is 0
elapsed := time.Since(start)
fmt.Printf("Elapsed: %v\n", elapsed)

Burada kodla oynayabilirsiniz .


0
package main

import (
    "fmt"
    "time"
)

func receiver(ch <-chan int) {
    time.Sleep(500 * time.Millisecond)
    msg := <-ch
    fmt.Printf("receive messages  %d from the channel\n", msg)
}

func main() {
    start := time.Now()
    zero_buffer_ch := make(chan int, 0)
    go receiver(zero_buffer_ch)
    zero_buffer_ch <- 444
    elapsed := time.Since(start)    
    fmt.Printf("Elapsed using zero_buffer channel: %v\n", elapsed)

    restart := time.Now()
    non_zero_buffer_ch := make(chan int, 1)
    go receiver(non_zero_buffer_ch)
    non_zero_buffer_ch <- 4444
    reelapsed := time.Since(restart)
    fmt.Printf("Elapsed using non zero_buffer channel: %v\n", reelapsed)
}

sonuç:

kanaldan mesajlar 444 al

Zero_buffer kanalı kullanılarak geçen: 505.6729ms

Zero_buffer olmayan kanal kullanılarak geçen: 0s

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.