go - 为什么所有的 goroutines 都在 sleep ?

标签 go concurrency deadlock channel goroutine

代码如下;

package main

import "fmt"

func main() {
    func1(1)
}

func func1(n int) {
    ch := make(chan int)
    ch <- 1
        for i := range ch {
            fmt.Println(i)
            fmt.Println(<-ch)
        }   
}

当我尝试执行这段代码时,它会抛出以下错误;

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.func1(0x1, 0x432070)
    /tmp/sandbox451742015/main.go:11 +0x60
main.main()
    /tmp/sandbox451742015/main.go:6 +0x20

最佳答案

你的 channel 是无缓冲的,所以第一次发送会阻塞,直到有人从它那里收到。但是从它那里接收的代码在那之后,所以这是一个“立即”死锁。

你可以让它像 ch := make(chan int, 1) 一样无缓冲,所以发送不会阻塞,但是你有一个 goroutine 有一个 for range 通过 channel 。此循环仅在 channel 关闭时退出,但您永远不会关闭它。而且您只在其上发送一个值,因此循环被阻塞,等待它可以接收的值或 channel 关闭。

您需要另一个 goroutine 来关闭 channel 。在循环内部,您不需要再次从 channel 接收,循环结构已经做到了。 i 将是从 channel 接收到的值。

有意义的工作示例:

func func1(n int) {
    ch := make(chan int)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)
    }()
    for i := range ch {
        fmt.Println(i)
    }
}

此输出(在 Go Playground 上尝试):

0
1
2
3
4

关于go - 为什么所有的 goroutines 都在 sleep ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54998057/

相关文章:

go - 如何评估外部go源代码 "dynamically"?

Python distutils.扩展 : setting a concurrency level

c++ - std::atomic bool 变量的访问顺序

java - 什么时候 AtomicInteger 优于同步?

mysql - Spring @Transactional 死锁

python - 如何用python调试死锁?

go - 在没有验证的情况下解码 JWT 并找到范围

go - 在Golang中导入C错误: cc1.exe: error: too many filenames given

c++ - C++ GRPC客户端与golang服务器连接错误

java - AWT-EventQueue 未从 Unsafe.park 唤醒