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

父goroutine退出后子goroutine未终止的原因是什么?

父Goroutine结束后子Goroutine未退出的原因分析

示例代码

func sleep(d time.Duration, ch chan<- int) {
    fmt.Println("Sleeping...")
    time.Sleep(d)
    fmt.Println("Awake...")
    ch <- 0
}

func parent(ctx context.Context) int {
    ch := make(chan int, 1)

    go sleep(3*time.Second, ch)

    select {
    case <-ctx.Done():
        return 1
    case <-ch:
        return 0
    }
}

func app(wg *sync.WaitGroup) {
    defer wg.Done()

    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()

    res := parent(ctx)

    fmt.Println(res)
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1)

    go app(&wg)

    wg.Wait()

    time.Sleep(2 * time.Second)
}

问题描述

在这个示例中,我设置了一个超时时间为2秒的ctx。子goroutine(sleep函数)需要3秒才能完成执行。2秒后,parent函数因触发<-ctx.Done()分支返回1。但在主线程中我再休眠2秒后,发现子goroutine并未退出,仍在继续执行并打印"Awake..."。

为何父goroutine结束后子goroutine没有退出?

程序输出

Sleeping...
1
Awake...

原因解析

Go语言里,goroutine之间不存在默认的"父子依赖"关系——父goroutine的退出不会主动终止子goroutine。只要子goroutine的代码还没执行完,它就会继续运行直到自身逻辑完成,完全不受创建它的父goroutine状态影响。

具体到你的代码流程:

  1. parent函数启动sleep子goroutine后,进入select语句等待事件;
  2. 2秒后ctx触发超时,parent函数返回1,随后app函数执行完毕并调用wg.Done();
  3. 此时sleep子goroutine还在执行time.Sleep(3*time.Second),它没有任何机制感知到父goroutine已经结束;
  4. 当3秒休眠结束后,子goroutine会继续执行后续代码:打印"Awake...",然后向缓冲通道ch发送数据——因为ch容量为1,发送操作不会阻塞,子goroutine执行完所有代码后才会退出。

解决方案:让子goroutine响应父goroutine的退出

如果需要子goroutine随父goroutine的退出而终止,需要主动传递取消信号:

  • 修改sleep函数,让它接收context.Context参数,在执行过程中检查取消信号;
  • 利用context的取消机制,让子goroutine感知到父goroutine的退出事件。

修改后的sleep函数示例:

func sleep(ctx context.Context, d time.Duration, ch chan<- int) {
    fmt.Println("Sleeping...")
    select {
    case <-ctx.Done():
        fmt.Println("Sleep goroutine canceled")
        return
    case <-time.After(d):
        fmt.Println("Awake...")
        ch <- 0
    }
}

同时在parent函数中把ctx传递给sleep:

go sleep(ctx, 3*time.Second, ch)

这样当ctx超时后,子goroutine会立即收到取消信号,提前退出,不会再执行后续的打印和发送操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:15:29