go - 选择 channel 时陷入死锁

标签 go concurrency channel goroutine

package main

import (
    "fmt"
    "time"
)

func Server1(ch chan string) {
    time.Sleep(2*time.Second)
    ch <- "from Server-1"
}

func Server2(ch chan string) {
    time.Sleep(3*time.Second)
    ch <- "from Server-2"
}

func main() {
    input1 := make(chan string)
    input2 := make(chan string)
    
    go Server1(input1)
    go Server2(input2)
    
    for {
        select {
            case s1 := <- input1:
                fmt.Printf(s1 + "\n")
            case s2 := <- input2:
                fmt.Printf(s2 + "\n")   
        }
    }
}

运行上面的代码,得到如下错误

from Server-1
from Server-2
fatal error: all goroutines are asleep - deadlock!

在这个 channel 选择中,我们有两个线程以不同的计时器间隔运行,为什么会出现死锁?

最佳答案

您启动了 2 个 goroutine,它们仅在其 channel 上发送单个值,然后它们将终止,因此 main 函数将单独卡在那里。这就是僵局的原因。

如果修改 Server1()Server2() 以无休止地发送值,则不会出现死锁:

func Server1(ch chan string) {
    for {
        time.Sleep(2 * time.Second)
        ch <- "from Server-1"
    }
}

func Server2(ch chan string) {
    for {
        time.Sleep(3 * time.Second)
        ch <- "from Server-2"
    }
}

关于go - 选择 channel 时陷入死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64996760/

相关文章:

json - 在 go 中键入嵌套的 json 解码

go - 尝试编写自定义规则

audio - Directshow中音频 channel 的数量大于2时,如何控制每个 channel 的音量?

concurrency - 在函数中将 channel 作为参数传递的不同方法

java - Java中高效同步列表

c# - 具有重复调用的 WCF channel 生命周期

go - 在测试Buffalo应用程序期间禁用信息日志

go - 简单的 Go Web 服务器,在客户端中看不到响应

concurrency - 并发模型列表

Java ConcurrentHashMap 操作原子性