← 中文资源

简体中文版本

Go 扇出扇入流水线

把输入扇出给多个工作 goroutine 并计算平方,再通过单一通道扇入汇总,用索引把乱序结果还原成输入顺序。

阅读英文原文

功能说明

process 把输入切片扇出给多个工作 goroutine 计算平方,再通过一个共享的 outputs 通道扇入汇总。每个结果携带原始下标,收集阶段按下标写回预分配切片,因此最终顺序与输入完全一致。所有工作者结束后关闭输出通道,主协程用 seen 标记检查是否有结果缺失。

关键代码

for index, value := range inputs {
	select {
	case jobs <- indexed{index: index, value: value}:
	case <-ctx.Done():
		return
	}
}
...
results[output.index] = output.value
seen[output.index] = true

下标是恢复顺序的关键;如果直接 append,结果顺序会随调度变化。

使用注意

  • 发送与接收分支都监听 ctx.Done(),避免取消后仍有 goroutine 永久阻塞。
  • 输入很长时,jobs 与 outputs 都是无缓冲通道,吞吐由最慢的一环决定。
  • 取消后函数返回错误并丢弃已完成结果;如果需要部分结果,可先返回切片再附带错误。
  • 重复下标会覆盖前一个结果,调用方应保证输入下标唯一。
  • 每个工作者只做纯计算,真实场景应把耗时 I/O 放进 worker 并控制并发度。

验证方式

示例输出应为 [9 1 16 1 25 81 4 36],与输入顺序一致。把 workers 改为 1 或 8,结果不变;在发送前取消上下文,可验证函数返回 context.Canceled。