我的问题来自尝试使用select语句读取(如果可以)或编写(如果可以)的通道。
select
我知道指定的通道make(chan bool, 1)被缓冲,并且我的问题的一部分是那之间的区别,并且make(chan bool)- 该页面说的内容与make(chan bool, 0)-–可以容纳0值的通道的意义是什么?它?
make(chan bool, 1)
make(chan bool)
make(chan bool, 0)
见 游乐场A :
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外壳会导致死锁!)
default
现在看 游乐场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中一样,该通道永远不会被读取 或 写入。我对频道的了解缺少什么?
通道中可以容纳0值的点是什么
首先,我想指出的是,这里的第二个参数表示缓冲区大小,因此这只是一个没有缓冲区的通道(未缓冲的通道)。
实际上,这就是产生您的问题的原因。非缓冲通道仅在有人阻止读取时才可写,这意味着您将需要使用一些协程-而不是单个协程。
另请参阅Go内存模型:
来自未缓冲通道的接收发生在该通道上的发送完成之前。