go - 为什么 goroutine 中的无缓冲通道得到这个顺序
问题描述
我正在用 goroutine 和通道编写一些 golang 并发代码,这是我的代码:
package main
import "fmt"
func main() {
in := make(chan int)
go func() {
fmt.Println("Adding num to channel")
in <- 1
fmt.Println("Done")
}()
val := <- in
fmt.Println(val)
}
我做了一个无缓冲的通道,在我看来,里面的通道必须等到外面的通道读取它,输出可能是这样的:
Adding num to channel
1
Done
但实际上,输出是:
Adding num to channel
Done
1
我很困惑,为什么内部无缓冲通道无需等待读取就运行
解决方案
您对输出的解释不正确。goroutine 确实写入了通道,此时主 goroutine 确实读取了,但是“完成”的 printf 在值的 printf 之前执行。
同步操作在 goroutine 之间建立了“之前发生过”的关系。当 goroutine 写入通道时,唯一能保证在通道写入之前发生的事情是 goroutine 中的第一个 println。一旦通道写入和相应的读取完成,剩下的 goroutine 和主 goroutine 可以以任意顺序执行。
在您的情况下,goroutine 在主 goroutine 之前执行。
推荐阅读
- javascript - 在遍历 jquery 中的元素时如何查询子元素?
- go - golang slice [:] 匹配最后一个元素
- prolog - 检查两个连接列表是否等于 Prolog 中的第三个列表
- php - Laravel 数据库事务不工作
- amazon-web-services - EC2依赖elb时出现AWS循环依赖错误
- c# - 在 C# 中,有没有办法在 Powerpoint 演示文稿中重新建立与嵌入式 Excel 工作簿的丢失 RPC 连接?
- mysql - 将mysql查询输出到shell脚本
- c++ - 全局变量不更新自身 - C++
- java - 为什么重写的方法应该在这个程序中公开?
- r - https://r-forge.r-project.org/ 和其中的包不起作用