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

Go语言Goroutines提前休眠问题:代码运行异常求助

Go通道与协程代码问题分析及修复

问题原因

  • 一次性协程导致无接收者:b函数中仅启动了两个单次接收的协程,它们接收一次link通道的数据后就立即退出。后续a函数继续向link发送消息时,由于无缓冲通道要求发送方和接收方同时就绪,发送操作会永久阻塞,a无法完成20次循环,stop通道永远不会收到信号,最终程序触发死锁。

解决方法

  • 让b内的两个协程持续监听link通道,直到通道被关闭;
  • 在a函数完成循环后,关闭link通道,告知接收协程停止工作;
  • 确保所有协程能正常退出,避免资源泄漏。

修改后的代码

package main

import (
    "fmt"
    "time"
)

func main() {
    link := make(chan bool)
    stop := make(chan bool)
    go a(link, stop)
    go b(link)
    <-stop
}

func a(link chan bool, stop chan bool) {
    for i := 0; i < 20; i++ {
        time.Sleep(1 * time.Second)
        link <- true
    }
    close(link) // 发送完成后关闭通道,通知接收方停止
    stop <- true
}

func b(link chan bool) {
    // 协程持续接收直到通道关闭
    go func() {
        for range link {
            fmt.Println("A")
        }
    }()
    // 协程持续接收直到通道关闭
    go func() {
        for range link {
            fmt.Println("B")
        }
    }()
}

修改后,a每秒发送一次数据,两个协程会各自持续接收并打印"A"、"B",直到20次发送完成,link通道关闭,协程自动退出,最后stop通道触发,主程序正常结束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:03:16