这是对 go中关于chan应用的程序分析 文章中代码的流水流水线示意图。
- 我们假设gen,sq和print操作需要的时间单位都是1:
time |
gen |
sq |
Print |
1 |
out:1 |
|
|
2 |
out:2 |
out: 1 |
|
3 |
out:3 |
out: 4 |
1 |
4 |
out:4 |
out: 9 |
4 |
5 |
out:5 |
Out: 16 |
9 |
6 |
out:6 |
Out: 25 |
16 |
7 |
out:7 |
Out: 36 |
25 |
8 |
out:8 |
Out: 49 |
36 |
9 |
close(out) |
close(out) |
done<- |
我们假设gen,sq和print没一个处理步骤是相同的,那我们就可以明显的看到一个流水线的形式,而最后我们给done这个通道推入数据,gen,sq同时关闭并退出。
- 但是在程序的主体运行部分,sq函数通常需要更多的时间进行数据运算或其他相关的操作。我们假设sq的需要2个时间单位。
time |
gen |
sq |
Print |
1 |
1 |
|
|
2 |
2 |
1 |
|
3 |
blocked |
going |
|
4 |
3 |
4 |
1 |
5 |
blocked |
going |
waiting |
6 |
4 |
9 |
4 |
7 |
blocked |
going |
waiting |
8 |
5 |
16 |
9 |
9 |
close(out) |
close(out) |
done<- |
由于sq需要2个时间单位来进行运算,这就导致了上游方法gen输出通道阻塞,和下游方法print读取通道等待。增加了时间的消耗。
- 由于sq需要消耗2个时间单位所以我们开启2个sq函数,同时用一个merge函数处理两个sq函数的通道输出。如下:
time |
gen |
Sq1 |
Sq2 |
Merge |
Print |
1 |
1 |
|
|
|
|
2 |
2 |
1 |
|
|
|
3 |
3 |
Going |
4 |
|
|
4 |
4 |
9 |
Going |
1 |
|
5 |
5 |
Going |
16 |
4 |
1 |
6 |
6 |
25 |
Going |
9 |
4 |
7 |
7 |
Going |
36 |
16 |
9 |
8 |
8 |
49 |
Going |
25 |
16 |
9 |
close(out) |
close(out) |
close(out) |
close(out) |
done<- |
在这个流水线中,用了两个sq和一个merge作为中间函数来进行数据处理。这样同样在9个时间单位内我们可以输出4个值,同时也不会造成阻塞等行为。
time |
gen |
Sq1 |
Sq2 |
Sq3 |
Merge |
Print |
1 |
1 |
|
|
|
|
|
2 |
2 |
1 |
|
|
|
|
3 |
3 |
Going |
4 |
|
|
|
4 |
4 |
|
Going |
9 |
1 |
|
5 |
5 |
|
16 |
Going |
4 |
1 |
6 |
6 |
25 |
Going |
|
9 |
4 |
7 |
7 |
Going |
36 |
|
16 |
9 |
8 |
8 |
|
Going |
49 |
25 |
16 |
9 |
close(out) |
close(out) |
close(out) |
|
close(out) |
done<- |
这时可以看出,如果通道开的多了之后总会有一部分通道没有处于满负荷运转,这样会增加我们的空间消耗。
time |
gen |
Sq1 |
Sq2 |
Sq3 |
Merge |
Print |
1 |
1 |
|
|
|
|
|
2 |
2 |
1 |
|
|
|
|
3 |
3 |
Going |
4 |
|
|
|
4 |
4 |
Going |
Going |
9 |
|
|
5 |
5 |
16 |
Going |
Going |
1 |
|
6 |
6 |
Going |
25 |
Going |
4 |
1 |
7 |
7 |
Going |
Going |
36 |
9 |
4 |
8 |
8 |
49 |
Going |
going |
16 |
9 |
9 |
close(out) |
close(out) |
close(out) |
|
close(out) |
done<- |
在这个流水线中,开三个通道,同时sq的处理时间是3个时间单位,正好每个协程都在运转且不会造成阻塞或等待的现象。
由此可知,我们在一个pipeline中,其中的一个部分是否并行主要根据各子程序运行一次的时间来判断,运行时间越长,越应该用多个协程处理。
用拓扑图进行表示:
|
请发表评论