96

我正在尝试创建一个异步通道,并且一直在查看http://golang.org/ref/spec#Making_slices_maps_and_channels

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

缓冲区大小为 10 是什么意思?缓冲区大小具体代表/限制什么?

4

3 回答 3

182

缓冲区大小是可以在没有发送阻塞的情况下发送到通道的元素数。默认情况下,通道的缓冲区大小为 0(您可以使用 获得make(chan int))。这意味着每次发送都会阻塞,直到另一个 goroutine 从通道接收。缓冲区大小为 1 的通道可以容纳 1 个元素,直到发送块,所以你会得到

c := make(chan int, 1)
c <- 1 // doesn't block
c <- 2 // blocks until another goroutine receives from the channel
于 2012-08-13T23:52:42.620 回答
18

以下代码说明了无缓冲通道的阻塞:

// 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)

你可以在这里玩代码。

于 2016-10-07T14:18:54.600 回答
2
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)
}

结果:

从频道接收消息 444

使用 zero_buffer 通道经过:505.6729ms

使用非 zero_buffer 通道经过:0s

于 2018-07-27T04:57:58.233 回答