首页 > 文章列表 > Golang 中执行了 context 的 Cancel,但

Golang 中执行了 context 的 Cancel,但

261 2025-04-07

Golang 中执行了 context 的 Cancel,但

为什么 golang 中执行了 context 的 cancel,但 <- ctx.done() 却没有执行?

在给定的代码示例中,gen 函数生成一个通道,在收到 ctx.done() 信号时打印 "done",否则生成并发送一个数字。main 函数使用 withcancel 创建了一个有取消功能的 context,并通过调用 cancel 取消它。

预期的是,当执行 cancel() 时,<- ctx.done() 应该立即执行,打印 "done"。但是,在给定的代码中,这并没有发生。这是因为代码在取消 context 之前已经阻塞在 ch<-n 上了。

解决这个问题的方法是在 gen 函数中在关闭 context 时关闭通道。这将导致 range 循环结束,并允许 <- ctx.done() 执行。修改后的 gen 函数如下:

func gen(ctx context.Context) <-chan interface{} {
    ch := make(chan interface{})
    go func() {
        n := 0
        for {
            select {
            case <-ctx.Done():
                fmt.Println("done")
                close(ch) // 关闭通道,range 结束
                return
            default:
                n += 1
                ch <- n
            }
        }

    }()
    return ch
}
来源:1731459700