go - 具有通道参数的函数中的死锁
问题描述
给定以下简单的 Go 程序:
ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2
如果我替换go fmt.Println(<- ch)
为go func(){fmt.Println(<-ch)}()
,则效果很好。
但是对于原始版本,我得到:
fatal error: all goroutines are asleep - deadlock!
为什么?
解决方案
如规范中所定义:
函数值和参数在调用 goroutine 中像往常一样被评估,但与常规调用不同,程序执行不会等待调用的函数完成。相反,该函数开始在一个新的 goroutine 中独立执行。当函数终止时,它的 goroutine 也会终止。如果函数有任何返回值,它们会在函数完成时被丢弃。
所以<-ch
被评估了。但它不能,因为通道是空的,因此它会阻塞,直到有东西写入它。但是没有任何东西写入它,因此这是一个死锁。
当您将它包装在匿名函数中时 - 会发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。
推荐阅读
- c# - 如何在ListView c#上显示列表中大于1的所有数字
- python - 我无法安装opencv python
- java - 如何检查列表是否存在于java中的列表中
- sql - 如何从变量和临时表中删除 CTE 中的重复项
- hiredis - 使用 HIREDIS 流水线后不检查回复
- vue.js - Vue - 当我在 2 个卡片选项卡之间切换时,tinyMCE 消失了
- tensorflow - 无法从 tensorboard 运行 tsne 以获取少量样本?
- amazon-web-services - 使用 golang sdk 将本地 docker 镜像上传到 AWS ECR
- python - python any() 用于检查条件
- bash - 如何使“echo -e”或“printf”在 git submodule foreach 中工作?