channel 与 context 协作

更新时间:2025.05.29

← 返回首页
Gogoroutinecontext

让 context 负责取消,让 channel 传递数据

channel 擅长在 goroutine 之间传递值,context.WithCancel 则把退出信号沿调用链传播。长时间运行的 worker 应在每次可能阻塞的位置检查 ctx.Done()

ctx, cancel := context.WithCancel(parent)
defer cancel()

select {
case job := <-jobs:
    process(job)
case <-ctx.Done():
    return ctx.Err()
}

不再建议把一个永远不会写入的 done channel 到处传递;需要兼容旧代码时可以保留它,但用 context 统一入口更容易追踪超时和取消原因。

避免泄漏

for {
    select {
    case v, ok := <-results:
        if !ok { return }
        consume(v)
    case <-ctx.Done():
        return
    }
}

带 deadline 的 context 应由最接近请求边界的调用方创建,底层函数只接收并传递它,避免悄悄延长超时。

对 worker pool 来说,先关闭 jobs,再等待 worker 退出,最后关闭 results,能让所有权关系更清楚。

相关笔记