这似乎挑战了我对无缓冲通道的理解,即它只能采用一个值,然后它会阻止读者读取它。
writeToChan
如何能够写入3个值?摘录自 https://golang.org/doc/ effective_go#channels
接收器总是阻塞,直到有数据要接收。如果通道未缓冲,则发送方会阻塞,直到接收方收到该值。如果通道有缓冲区,则发送方只会阻塞,直到该值被复制到缓冲区为止;如果缓冲区已满,这意味着等待某个接收器检索到值。
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go writeToChan(ch)
go rdFrmChan(ch)
x := <- ch
fmt.Println("main read 1 -:",x)
fmt.Println("main read 2 -:",<-ch)
}
func writeToChan(c chan int) {
time.Sleep(time.Second * 1)
c <- 42
c <- 27
c <- 9
}
func rdFrmChan(c chan int) {
fmt.Println("Go routine read :", <-c)
}
输出:
Go routine read : 27<br>
main read 1 -: 42<br>
main read 2 -: 9<br>
如果您了解事件发生的顺序,则粘贴的每一行摘录都由示例代码证明。
goroutines 启动后,您的主例程将被阻止从通道读取
c
,因为它还没有看到要读取的值。 writeToChan
例程在将第一个值写入通道之前等待一秒钟
goroutine
rdFrmChan
也被阻塞,因为它正在等待通道上的读取 ch
1秒后,当
writeToChan
上的睡眠到期时,第一次写入(c <- 42
)将首先解锁您的主例程,导致该值存储在x
中,即42
接下来,
rdFrmChan
在下一次写入通道时被解除阻塞(c <- 27
)并看到值27。在打印该值后,例程在此时终止
此时,只有一个要写入的值和一个要读取的值。来自 goroutine 的第三次写入 (
c <- 9
) 允许主例程读取该值作为 <-ch
的一部分并打印它