go - channel 仅从 Println in go routine 接收抛出死锁异常

标签 go

我有一些代码,我试图使用 fmt.Println 在 goroutine 中打印 channel 的内容。这是代码的简化版本。

package main

import "fmt"
import "time"

func main() {
  ch := make(chan int)
  go fmt.Println(<-ch);
  ch<- 10;
  time.Sleep(time.Second * 10);
}

当我运行上面的代码时,出现了这个错误。

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        C:/cygwin64/home/vmadhusudana/go/channel.go:9 +0x67
exit status 2

但是当我从函数调用 fmt.Println 时它工作正常

package main

import "fmt"
import "time"

func main() {
    ch := make(chan int)
    go func(){fmt.Println(<-ch)}();
    ch<- 10;
    time.Sleep(time.Second * 10);
}

这里有什么不同?

最佳答案

在第一个版本中, channel 读取是从主 go-routine 执行的 - 因此会出现死锁。 第二个版本,读取是从创建的 go-routine 完成的。

基本上是这样的:

go fmt.Println(<-ch);

变成:

v := <-ch
go fmt.Println(v);

因为函数的参数是在调用之前计算的。

附言defer 语句的行为类似。因此,如果您希望传递给 go-routine 或 defer 语句的值在“运行时”进行评估,请始终使用闭包。

关于go - channel 仅从 Println in go routine 接收抛出死锁异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55790343/

相关文章:

go - 如何使用 gocql 优化 scylla db 的交叉分片查询

go - Golang 中用于匹配传递的变量和类型的通用函数

github - 为什么不能构建 godef.go?

postgresql - 将 postgresql jsonb 查询响应字符串解码为 golang 嵌套结构

angularjs - Go + Angular 用户界面路由器

arrays - 使用公共(public)键 golang 合并两个 JSON 数组

c - 如何将 GoLang 结构方法作为 C 回调传递

go - 如何使用 Go 语言获取中文首字母(拼音)?

go - 在Golang中使用上下文超时停止运行功能

go - 在 Golang 中定期爬取 API