【发布时间】:2013-12-01 05:25:07
【问题描述】:
我的问题来自于尝试读取频道(如果可以),或者尝试使用select 语句写入频道。
我知道像make(chan bool, 1) 这样指定的频道被缓冲了,我的部分问题是这之间有什么区别,而make(chan bool)——this page 说的和make(chan bool, 0) 一样——可以在其中容纳 0 值的通道有什么意义?
chanFoo := make(chan bool)
for i := 0; i < 5; i++ {
select {
case <-chanFoo:
fmt.Println("Read")
case chanFoo <- true:
fmt.Println("Write")
default:
fmt.Println("Neither")
}
}
输出:
Neither
Neither
Neither
Neither
Neither
(删除default 会导致死锁!!)
现在见playground B:
chanFoo := make(chan bool, 1) // the only difference is the buffer size of 1
for i := 0; i < 5; i++ {
select {
case <-chanFoo:
fmt.Println("Read")
case chanFoo <- true:
fmt.Println("Write")
default:
fmt.Println("Neither")
}
}
B 输出:
Write
Read
Write
Read
Write
就我而言,B 输出 是我想要的。无缓冲通道有什么好处?我在 golang.org 上看到的所有示例似乎都使用它们一次发送一个信号/值(这就是我所需要的)——但就像在游乐场 A 中一样,通道永远不会被读取 or书面。在我对渠道的理解中,我在这里遗漏了什么?
【问题讨论】:
-
"什么是通道可以容纳0值"这里的第二个参数表示缓冲区大小,所以这只是一个没有缓冲区的通道(无缓冲通道)
-
如果 Read 和 Write 在不同的 goroutines 中,示例 A 可以工作。默认通道,没有容量,是无缓冲的:发送一些东西会阻塞发送方,直到接收方从通道中读取,所以你需要将两者放在不同的 goroutines 中。
-
@siritinga 如果您将其扩展为答案,我想就是这样。因此,非缓冲通道会阻塞,除非有人已经在等待它,而大小为 1 的缓冲通道将保持值直到有人准备好接收它。