通道缓冲区大小是什么?

huangapple go评论86阅读模式
英文:

What is channel buffer size?

问题

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

c := make(chan int, 10) // 缓冲大小为10的通道

缓冲大小为10是什么意思?具体来说,缓冲大小表示/限制了什么?

英文:

I'm trying to create an asynchronous channel and I've been looking at http://golang.org/ref/spec#Making_slices_maps_and_channels.

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

What does it mean that the buffer size is 10? What specifically does the buffer size represent/limit?

答案1

得分: 203

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

c := make(chan int, 1)
c <- 1 // 不会阻塞
c <- 2 // 阻塞,直到另一个goroutine从通道接收
英文:

The buffer size is the number of elements that can be sent to the channel without the send blocking. By default, a channel has a buffer size of 0 (you get this with make(chan int)). This means that every single send will block until another goroutine receives from the channel. A channel of buffer size 1 can hold 1 element until sending blocks, so you'd get

c := make(chan int, 1)
c &lt;- 1 // doesn&#39;t block
c &lt;- 2 // blocks until another goroutine receives from the channel

答案2

得分: 21

以下代码演示了无缓冲通道的阻塞:

// 若要查看差异,请将0更改为1
c := make(chan struct{}, 0)
go func() {
time.Sleep(2 * time.Second)
<-c
}()
start := time.Now()
c <- struct{}{} // 如果通道大小为0,则阻塞
elapsed := time.Since(start)
fmt.Printf("Elapsed: %v\n", elapsed)

您可以在此处尝试运行代码(https://play.golang.org/p/KHkrkxCVdQ)。

英文:

The following code illustrates the blocking of unbuffered channel:

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

You may play with the code here.

答案3

得分: 2

package main

import (
"fmt"
"time"
)

func receiver(ch <-chan int) {
time.Sleep(500 * time.Millisecond)
msg := <-ch
fmt.Printf("从通道接收到消息 %d\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("使用零缓冲通道的时间: %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("使用非零缓冲通道的时间: %v\n", reelapsed)

}

英文:
package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

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

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

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

result:

receive messages 444 from the channel

Elapsed using zero_buffer channel: 505.6729ms

Elapsed using non zero_buffer channel: 0s

huangapple
  • 本文由 发表于 2012年8月14日 07:49:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/11943841.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定