这似乎挑战了我对无缓冲通道的理解,即它只能接受一个值,然后它会阻止读取器读取它。
1.在下面的代码中,writeToChan
是如何写3个值的?
1.更令人惊讶的是,这些值如何在以后被读取,尽管顺序不同?
摘自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>
Playground链接:https://play.golang.org/p/DYzfYh-kXnC
1条答案
按热度按时间fykwrbwg1#
如果您了解事件发生的顺序,则粘贴的摘录的每一行都可以通过示例代码进行验证。
1.在goroutines启动之后,你的主例程被阻塞阅读,因为它还没有看到一个要读取的值。
writeToChan
例程在将第一个值写入通道之前等待一秒钟rdFrmChan
也被阻塞,因为它正在等待读取通道ch
。writeToChan
上的休眠到期时,第一次写入(c <- 42
)将首先解除主例程的阻塞,导致值存储在x
中,即421.接下来,
rdFrmChan
在下一次写入通道(c <- 27
)时被解除阻塞,并看到值27。打印值后,例程在此时终止1.此时,只有一个值要写入,一个值要读取。goroutine的第三次写入(
c <- 9
)允许主例程读取<-ch
的值并打印出来