Go程序退出时未等待goroutine完成会导致流水线中断;需用sync.WaitGroup或done channel显式同步,避免goroutine因main退出被强制终止或channel阻塞。

流水线没跑完就退出,不是代码写错了,而是 goroutine 生命周期没管住。
goroutine 启动后立刻返回,main 就 exit 了
常见错误是 startorder 函数启动 position0 goroutine 后直接 return,main 函数不等它执行完就结束。Go 程序退出时,所有 goroutine 被强制终止,打印语句根本来不及执行。
- 必须用
sync.WaitGroup或done chan struct{}显式等待下游阶段完成 -
WaitGroup更适合“固定数量、已知阶段”的流水线;done channel更适合动态增删阶段或需要提前中断的场景 - 别在
main里只调用函数就不管了——启动 goroutine ≠ 执行完成
channel 没关、没人读,goroutine 卡死在 send 或 receive
比如 position0 从 in chan orderstruct 读数据,但上游没 close,下游又没消费它的输出,整个 goroutine 就会永久阻塞在 out 上(如果 <code>out 是无缓冲 channel)。
- 每个阶段的输入 channel 应由上游负责 close,输出 channel 应有下游明确接收
- 用
for range in自动处理关闭信号,比手动select+ok判断更简洁安全 - 有缓冲 channel(如
make(chan order, 10))能缓解阻塞,但不能替代生命周期管理
流水线阶段之间类型不匹配或方向反了
Go 的 channel 类型是双向且带方向的: 只能读,<code>chan 只能写。传错方向会导致编译失败;类型不一致(比如传 <code>chan int 给期望 chan string 的函数)也会报错。
立即学习“go语言免费学习笔记(深入)”;
- 函数签名要严格匹配:生产者返回
,消费者参数用 <code>,中间处理函数参数/返回都用 <code> - 别图省事全用
chan T——失去编译期类型保护,后期调试成本飙升 - 多个阶段串联时,确保前一阶段的
out类型和下一阶段的in类型完全一致
为什么不用 WaitGroup 而用 done channel?
WaitGroup 适用于阶段数固定、拓扑静态的流水线;但真实业务中常需支持“某个阶段失败就整体退出”或“超时强制关闭”,这时 done channel 更灵活。
-
done可被多个 goroutine 同时监听,一个 close 全部响应;WaitGroup需每个 goroutine 单独Done() - 结合
select使用:case 能让 goroutine 主动退出,避免残留 - 注意:
close(done)只能调用一次,重复 close 会 panic;建议封装成函数或用sync.Once
实际跑通一条流水线,最难的从来不是写几个 go func() {}(),而是让所有 goroutine 在该停的时候停、该等的时候等、该传的数据不丢不卡。类型、channel 方向、关闭时机、同步机制——四个点漏掉任何一个,整条线就断在看不见的地方。


















