功能说明
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。