go - 在 Go 中如何向无缓冲通道写入/读取多个值?
问题描述
这似乎挑战了我对无缓冲通道的理解,即它只能取一个值,然后它会阻止读者阅读它。
- 如何在以下代码
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 例程读取:27
主读取 1 -:42
主读取 2 -:9
Playground link: https://play.golang.org/p/DYzfYh-kXnC
解决方案
如果您了解事件发生的顺序,则粘贴的每一行摘录都由您的示例代码证明。
在 goroutines 启动后,你的 main 例程被阻止从 channel 读取
c
,因为它还没有看到要读取的值。该writeToChan
例程在将第一个值写入通道之前等待一秒钟goroutine
rdFrmChan
也被阻塞了,因为它在 channel 上等待读取ch
1s后,当sleep on
writeToChan
过期时,第一次write(c <- 42
)会先解锁你的主程序,导致值存入x
ie 42接下来,
rdFrmChan
在下一次写入通道c <- 27
(此时,只有要写入的值和要读取的值。goroutine 中的第三个 write (
c <- 9
) 允许主例程读取值作为其一部分<-ch
并打印它
推荐阅读
- sql - 默认日期雪花:无效标识符“日期”
- github - Raku 的 VS Code 中的多行注释
- c# - 使用 EF6 和 MySQL 克隆实体时出现死锁
- vba - 根据内容选择组合框中的项目
- python - Span 的内联 pandas_bokeh 语法
- mysql - 如何从 JPA 自定义查询中的 SELECT 更新
- c++ - 使用带有 opt 的 pass “-targetpassconfig” 获取错误
- reactjs - How to render header component in order to show current user?
- android - In Android Compose, is it possible to always play an AnimatedVectorResource forwards?
- c - 偶数乘法的 C 代码返回 0