You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么这段Go语言交替打印代码会引发死锁?

Go交替打印代码的死锁原因分析

原死锁代码

func main() {
    oddCh := make(chan struct{})
    evenCh := make(chan struct{})
    done := make(chan struct{})

    go func() {
        defer close(evenCh)
        for i := 1; i < 10; i += 2 {
            <-oddCh
            fmt.Println(i)
            evenCh <- struct{}{}
        }
    }()

    go func() {
        defer close(done)
        for i := 2; i <= 10; i += 2 {
            <-evenCh
            fmt.Println(i)
            oddCh <- struct{}{}
            if i == 10 {
                close(oddCh)
                break
            }
        }
    }()

    oddCh <- struct{}{}

    <-done
}

执行输出结果

1
2
3
4
5
6
7
8
9
10
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    D:/Gocode/alternateprint/main.go:34 +0x125

goroutine 7 [chan send]:
main.main.func2()
    D:/Gocode/alternateprint/main.go:24 +0xcb
created by main.main in goroutine 1
    D:/Gocode/alternateprint/main.go:19 +0x105

死锁原因拆解

  1. 奇数goroutine的生命周期:它负责打印1、3、...、9,循环条件是i < 10,打印完9后循环直接结束,执行defer close(evenCh)就退出了,后续不会再接收oddCh的任何消息。
  2. 偶数goroutine的阻塞点:当i=10时,原代码先执行oddCh <- struct{}{}——由于oddCh是无缓冲通道,发送操作必须等到有接收者才能完成,但此时奇数goroutine已经退出,没有任何goroutine会接收这个发送的值,导致偶数goroutine卡在这个发送步骤上。
  3. 连锁阻塞触发死锁:偶数goroutine卡死后,无法执行后续的close(oddCh)和close(done),而main goroutine一直在等待<-done的信号,所有goroutine都进入阻塞状态,最终触发死锁。

交换顺序后的修复逻辑

将oddCh <- struct{}{}和i=10的判断代码交换顺序后,偶数goroutine的逻辑变为:

go func() {
    defer close(done)
    for i := 2; i <= 10; i += 2 {
        <-evenCh
        fmt.Println(i)
        if i == 10 {
            close(oddCh)
            break
        }
        oddCh <- struct{}{}
    }
}()

此时:

  • 处理i=10时,打印完成后直接关闭oddCh并跳出循环,不会执行oddCh <- struct{}{}的发送操作,避免了无接收者的阻塞问题。
  • 偶数goroutine退出前执行defer close(done),main goroutine从已关闭的done通道接收会立即返回,程序正常结束。

内容的提问来源于stack exchange,提问作者crazyfrank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:12:35