Golang语言社区-并发模型和应用场景
在Python中我们可以使用yield
关键字来让一个函数成为生成器,在Go中我们可以使用信道来制造生成器(一种lazy load类似的东西)。
当然我们的信道并不是简单的做阻塞主线的功能来使用的哦。
下面是一个制作自增整数生成器的例子,直到主线向信道索要数据,我们才添加数据到信道:
这不禁叫我想起了Python中可爱的xrange
, 所以给了生成器这个名字!
比如我们加载一个网站的时候,例如我们登入新浪微博,我们的消息数据应该来自一个独立的服务,这个服务只负责 返回某个用户的新的消息提醒。
如下是一个使用示例:
多路复合
上面的例子都使用一个信道作为返回值,可以把信道的数据合并到一个信道的。 不过这样的话,我们需要按顺序输出我们的返回值(先进先出)。
如下,我们假设要计算很复杂的一个运算 100-x , 分为三路计算, 最后统一在一个信道中取出结果:
select监听信道
Go有一个语句叫做select,用于监测各个信道的数据流动。
如下的程序是select的一个使用例子,我们监视三个信道的数据流出并收集数据到一个信道中。
有了select, 我们在 多路复合中的示例代码中的函数fanIn还可以这么来写(这样就不用开好几个goroutine来取数据了):
使用select的时候,有时需要超时处理, 其中的timeout信道相当有趣:
结束标志
在Go并发与并行笔记一我们已经讲过信道的一个很重要也很平常的应用,就是使用无缓冲信道来阻塞主线,等待goroutine结束。
这样我们不必再使用timeout。
那么对上面的timeout来结束主线的方案作个更新:
菊花链
简单地来说,数据从一端流入,从另一端流出,看上去好像一个链表,不知道为什么要取这么个尴尬的名字。。
菊花链的英文名字叫做: Daisy-chain, 它的一个应用就是做过滤器,比如我们来筛下100以内的素数(你需要先知道什么是筛法)
程序有详细的注释,不再说明了。
随机数生成器
信道可以做生成器使用,作为一个特殊的例子,它还可以用作随机数生成器。如下是一个随机01生成器:
定时器
我们刚才其实已经接触了信道作为定时器, time包里的After会制作一个定时器。
看看我们的定时器吧!