go - 为什么调用 goroutine 的顺序和方式很重要?
问题描述
我正在尝试理解 goroutines。在以下示例中,为什么 1)--4) 的行为不同?见https://play.golang.org/p/_XXZe47W53v
package main
import (
"fmt"
"time"
)
func send(x int, ch chan int) {ch<-x}
func read(ch chan int) {fmt.Println(<-ch)}
func main() {
ch := make(chan int)
go read(ch) // 1) works
go send(1,ch) // -> 1
// go fmt.Println(<-ch) // 2) fatal error: all goroutines are asleep - deadlock!
// go send(1,ch) // isn't this the same as the above ?
// go send(1,ch) // 3) works
// go fmt.Println(<-ch) // -> 1
// go fmt.Println(<-ch) // 4) fatal error: all goroutines are asleep - deadlock!
// go send(1,ch) // why does the order of the go routine calls matter?
time.Sleep(100*time.Millisecond)
}
解决方案
您看到错误是因为读取不是发生在 goroutine 内部,而是发生在主线程中。
该行:
go fmt.Println(<-ch)
正在评估主线程中的参数,一旦成功,它将Println
使用已解析的参数在 goroutine 中运行。由于ch
在这种状态下代码永远无法写入,它会死锁。
您可以通过将其更改为:
go func() { fmt.Println(<-ch) }()
ch
然后它会围绕send()
.
推荐阅读
- ios - main.jsbundle 不存在。升级到 react-native 0.63 后,这一定是一个错误。 main.jsbundle 问题
- salesforce - 如何将输入值从 Lightning 组件传递到流
- android - 触摸编辑文本时无法打开 DatePicker
- c++ - 使用 SFINAE 确保可变参数包参数派生为特定类型
- c++ - 是否应该在同一进程中使用 IUIAutomation 缓存请求?
- html - 为什么子div不浮动到右侧?
- python - Python 查找声明了类型别名(例如 Union,...)的文件
- javascript - 如何用烧瓶导入js文件?(Python)
- r - R 可反应 - 在 colDef 中应用多种样式
- html - 如何在 css 中做可点击的自定义下拉箭头?