go channel capacity 为什么比我指定的多了一个元素

标签 go channel

package main
import "fmt"
import "time"

func main() {
     message := make(chan string ,1) // no buffer
     count := 3

     go func() {
          for i := 1; i <= count; i++ {
               fmt.Println("send message")
               message <- fmt.Sprintf("message %d", i)
          }
     }()

     time.Sleep(time.Second * 3)

     for i := 1; i <= count; i++ {
          fmt.Println(<-message)
     }
}

输出是

send message
send message  [wait for 3 sec]
message 1
send message
message 2
message 3

如果我将 message := make(chan string ,1)//no buffer 更改为

message := make(chan string ,2) // no buffer

我得到了

send message
send message
send message [wait 3 sec]
message 1
message 2
message 3

为什么2个缓冲区 channel 可以存储3个字符串对象?不是 2?

谢谢,

最佳答案

之所以这样工作,是因为缓冲区在阻塞之前保存了 N 条消息。当 N+1 条消息进入时,GO 会发现它超出了您指定的容量,因此必须阻塞,等待从该 channel 获取内容。当传递缓冲区大小时,发送方将始终阻塞 N+1 条消息。

例如,对于大小为 2 的缓冲区,您有一个空缓冲区:

[][]

然后一条消息进来,被放入缓冲区:

[m1][]

然后另一个,我们可以继续前进,因为我们在缓冲区中有空间

[立方米][立方米]

然后另一个进来了,向上我们没有更多的缓冲区空间所以我们阻止

[m1][m2]m3 -> block

像这样。

大小基本上是可以在不阻塞的情况下发送到缓冲区的消息数。

对于 future 我推荐http://golang.org/doc/effective_go.html#channels

var sem = make(chan int, MaxOutstanding)

Once MaxOutstanding handlers are executing process, any more will block trying to send into the filled channel buffer, until one of the existing handlers finishes and receives from the buffer.

关于go channel capacity 为什么比我指定的多了一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25539649/

相关文章:

go - 存储 slice 的接口(interface){}上的范围

c# - WCF 协议(protocol)异常 : Bad Request 400 (related to http message size)

go - 使用 channel 或互斥体模拟 radio 通信

struct - 有没有办法强制转换结构以通过 channel 发送

go - 为什么在这个函数中使用 channel ?

clojure - 如何使用 core.async 实现天网 1m 微基准测试?

go - 导入 vault/builtin/credential/aws 将测试标志添加到命令行应用程序

python - 加载时找不到keras模型的输入层

go - 使用 golang Viper lib 进行高级配置

go - 我如何在 golang 中使用本地包?