go - 在 select 内发送到另一个 channel 会造成死锁

标签 go deadlock

发送到 select 内的另一个 channel 会造成死锁。我试图理解为什么会发生这种情况。是不是因为 select 语句持有它同时监听的所有 channel 的锁?
这是我用来测试它的代码片段:

package main

import (
        "fmt"
        "time"
)

func main() {
        c1:= make(chan int)
        c2:= make(chan int)

        go func() {
                time.Sleep(time.Second * 1)
                c2 <- 1
        }()

        for {
                select {
                case i := <-c1:
                        fmt.Println(i)
                case i := <-c2:
                        c1 <- i
                }
        }
}
这是输出:
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
        /home/user/test/main.go:22 +0x15e

最佳答案

使用 make(chan int) 创建的 channel 是 无缓冲 .发送和接收阻塞,直到对方准备好。
在您的示例中,您的主 goroutine 在 c1 <- i 上被阻止。等待某人接收来自c1 .但发生这种情况的唯一地方是同一个 goroutine 的上面三行。
我建议你通过 channels再次游览的部分,它涵盖了缓冲和非缓冲 channel 。

关于go - 在 select 内发送到另一个 channel 会造成死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63967425/

相关文章:

go - 将 []byte 数组(java 双编码)转换为 Float64

WPF同步动画和UI线程死锁

linux - 在 go-inotify 中观察递归目录

rest - 带有查询参数的golang Chi路由器不起作用

go - os.Mkdir 与 syscall.Mkdir,在 Golang 中有什么区别?

ios - dispatch_sync里面的dispatch_sync导致死锁

java - 如何检测 Netbeans 中的 Java 应用程序锁定?

xml - Golang XML 属性和值

c++ - 终止工作线程和主线程之间的竞争条件

java - 没有wait()和notify()的同步块(synchronized block)/方法notifyAll()方法