go标准库中没有通用的done()函数,唯一标准的是sync.waitgroup.done()方法,用于对计数器减一,必须与add()配对使用,否则可能panic。

Go语言中Done()不是标准库函数,别被名字误导
Go标准库没有叫 Done() 的通用任务完成函数。你看到的很可能是某个特定类型(比如 sync.WaitGroup、context.Context 衍生类型、或第三方包)里定义的方法,或者误把 Done() 当成“标记任务结束”的语义函数来用。Go 里真正用于协调任务完成的机制是组合式的:靠 sync.WaitGroup 计数、channel 通知、或 context.WithCancel 主动终止。
sync.WaitGroup.Done() 是唯一常见且标准的 Done() 方法
这是最可能匹配你搜索意图的实现——它不表示“任务逻辑完成”,而是表示“一个 goroutine 工作单元已退出”。它的作用非常具体:对内部计数器减一。
-
WaitGroup.Add(1)必须在启动 goroutine 前调用,不能在 goroutine 内部调用后再Done()—— 否则可能触发 panic:panic: sync: negative WaitGroup counter -
Done()必须和Add()配对;漏调、多调、在Wait()返回后调用都会出问题 - 不要在循环里反复
Add(1)+Done()而不控制并发数,容易耗尽资源;建议先Add(n),再启 n 个 goroutine,每个只调一次Done() - 示例片段:
var wg sync.WaitGroup for i := 0; i
别把 context.Context.Done() 当成“完成函数”来调用
ctx.Done() 是一个只读的 ,它**返回一个 channel**,用于监听取消信号,不是用来“调用”的函数。常见错误是写成 <code>ctx.Done()() 或试图“触发”它。
- 正确用法是 select 等待:
select { case - 主动结束任务靠的是父 context 的 cancel 函数(如
cancel()),不是子 context 的Done() - 如果你需要“手动标记任务完成”,应该自己发 signal 到 channel,而不是碰
ctx.Done() - 滥用
context.WithCancel并频繁调cancel()可能导致 goroutine 泄漏(没及时退出)或提前中断(cancel 太早)
没有“任务完成步调”这种内置抽象,得自己编排
Go 不提供类似 “任务生命周期钩子” 或 “完成回调队列” 的机制。所谓“步调”,实际是开发者根据场景组合原语的结果:
- 顺序完成:用
channel串行传递结果,或用sync.Once保底执行一次收尾逻辑 - 并行完成+汇总:用
sync.WaitGroup+ 共享结果切片(注意加锁或用sync.Map) - 带超时的完成:用
context.WithTimeout包裹,配合select监听Done()和结果 channel - 最容易被忽略的一点:完成 ≠ 安全退出。goroutine 退出前必须确保不再访问已释放的内存、关闭的 channel、或被回收的 context —— 这些不会报错,但会引发竞态或 panic
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











