Go 的一种并发模式:管道
Go 管道模式
开始
这片文章是看完 Golang 官方博客后写下,记录下。原文在这里
首先是 What is pipeline?官方博客上将管道看作是并发的程序的一种。一系列的 stage 通过 channel 串联起来。其中,每个 stage 都是一组执行相同任务的 goroutine。在每个 Stage 中,每个 goroutine 都会做三件事情:
- 通过一个 channel 接收到要处理的上游数据。
- 对接收的数据做处理,通常是产生一个新的值
- 将产生的新数据传入另一个 channel 中,传递到下游。
除了第一个和最后一个 Stage 以外,中间的 Stage 都会有几个传入和传出的数据通道,第一个只有传出,而最后一个只有传入。数据由第一个 stage 流入到最后一个 stage。
也就是说,在 Go 中的管道(pipeline)就像是一条生产线,一个零件从被生产到被消费,会经过几个不同的车间处理。第一个车间会生产最初的数据,而最后一个车间去消费这个数据。
为了更好的帮助理解,官方博客给出了例子。首先是最简单的一个例子:
1 |
|
Fan-out 和 Fan-in
fan-out: 多个程序从一个 channel 中读取数据,直到 channel 关闭。就像是一个管理人,分发工作给多个工人的情况。
fan-in: 与 fan-out 相反,一个程序从多个 channel 中读取数据,直到所有的 channel 都关闭了。于此同时,会将处理后的数据送入一个新的 channel 中,并在完成工作后关闭它。
例如,现在有一个 merge 函数:
1 |
|
原有的 gen 方法会被改造成下面的样子:
1 |
|
main 函数则变成:
1 |
|
通过设置一个名为 done 的 channel, 下游的程序可以给上游的程序发送信号,通知他们停止生产数据,作为了一个反馈途径。
因此,如果想要构建一个 pipeline 系统, 有以下的要点:
- 当所有的操作完成后,stage 关闭通向外界的 channel。
- stage 不断从流入 channel 中接收数据,直到这些 channel 关闭了或者是发送者解除阻塞状态。
Go 的一种并发模式:管道
https://blog.zhangliangliang.cc/post/go-concurrency-pipeline.html