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个缓冲区通道可以存储3个字符串对象?不是2?
感谢,
答案 0 :(得分:2)
它的工作方式与此类似,因为缓冲区在阻塞之前保存N条消息。当N + 1消息进入GO时,它将看到它超过您指定的容量,并且必须阻止,等待从该通道获取的内容。传递缓冲区大小时,发送方将始终阻止N + 1消息。
例如,对于大小为2,您有一个空缓冲区:
[] []
然后收到一条消息,放入缓冲区:
[M1] []
然后另一个,我们可以继续前进,因为我们在缓冲区中有空格
[M1] [平方米]
然后另一个进来,我们在缓冲区中没有更多的空间,所以我们阻止
[m1] [m2] m3 - &gt;块
像这样。
大小基本上是可以不阻塞地发送到缓冲区的消息数。
将来我推荐http://golang.org/doc/effective_go.html#channels
var sem = make(chan int, MaxOutstanding)
一旦MaxOutstanding处理程序正在执行进程,就会有更多 阻止尝试发送到填充的通道缓冲区,直到其中一个 现有的处理程序完成并从缓冲区接收。