暴露四个函数:
实现细节:
部件:
包: golang.org/x/sync/errgroup
作用:开启func() error函数签名的协程 , 在同 Group 下协程并发执行过程并收集首次 err 错误 。通过 Context 的传入,还可以控制在首次 err 出现时就终止组内各协程 。
设计思路:
结构:
暴露的方法:
实现细节:
注意问题:
包: "golang.org/x/sync/semaphore"
作用:排队借资源(如钱,有借有还)的一种场景 。此包相当于对底层信号量的一种暴露 。
设计思路:有一定数量的资源 Weight , 每一个 waiter 携带一个 channel 和要借的数量 n 。通过队列排队执行借贷 。
结构:
暴露方法:
细节:
部件:
细节:
包: "golang.org/x/sync/singleflight"
作用:防击穿 。瞬时的相同请求只调用一次,response 被所有相同请求共享 。
设计思路:按请求的 key 分组(一个 *call 是一个组,用 map 映射存储组),每个组只进行一次访问,组内每个协程会获得对应结果的一个拷贝 。
结构:
逻辑:
细节:
部件:
如有错误,请批评指正 。
channel使用【译文】 原文地址
channel是Go语言的一个标志性特性,为go协程之间的数据交互提供一种非常强大的方式 , 而不需要使用锁机制 。
本文将讨论channel的两个重要属性,一个是控制协程间数据发送和接收,以及对channel本身控制 。
首先讨论下关闭的channel特性 。一旦channel被关闭之后 , 就不能再继续发送数据给该channel,但是还是可以继续接收channel中的数据 。如下所示:
output:
上述例子显示即使ch在for循环之前已经关闭,但还是可以正常的读取缓存中的true值,读完之后ok就会被赋值为false表示channel已经关闭,而且value值为对应channel类型bool的默认零值false 。只要不停地从关闭的channel接收,就会无限的返回默认值和false 。可以将for循环次数改大点试试即可验证 。
通过以上例子可以发现 , 关闭的channel可以继续接收读取操作,这种特征是有用的 。在使用range读取带缓存的channel时就会用到,一旦channel关闭,读取完缓存中数据就会停止接收数据退出 。
将前面的例子改为如下:
output:
上面的例子就没有false打出来了 。正好是写入channel里面的两个值 。
channel与select结合更能发挥出其作用,让我们看一个例子:
上面的例子,因为finish在主协程中发送之后,马上就会在select中接收,并执行done.Done() 。主协程wait马上会退出整个程序就结束 。但是这里面存在一个问题,如果在select中没有添加finish case的话,主协程就永远发送不了数据到finish这个channel,因为其不带缓存 。这里就可以通过将finish改成带缓存的channel,或者可以让select中的finish不会阻塞 。
但是出现多个协程都在接收finish通道中的数据的话,就需要发送对应协程数量的值到channel中才能解决上面的问题 。但是具体有多少个协程这往往是不好确定的 , 因为有些协程可能是程序其他部分创建的 。一个比较好的选择就是通过使用关闭通道的方法来实现各协程能正常接收并结束 。
如下所示:
output:
上面的例子就是使用了关闭的channel可以无限地接收到反馈数据 。这样每个协程都能从finish通道中读到关闭信息并执行done.Done()使得主协程wait能退出 。并且不需要关注多少个协程数,就能正确的让所有协程读到finish通道信息 。
channel的这个特性,可以让程序员无需关注后台具体执行协程个数,确保每个协程都能接收到通道关闭信息,而无需担心死锁问题 。
推荐阅读
- sata硬盘怎么设置主从,sata主盘从盘设置图解
- html5中写循环,htmlfor循环
- 苹果食物店铺经营游戏下载,苹果经营餐厅类游戏
- 粉色直播平台软件,户外直播平台软件
- linux命令vim linux命令vi怎么退出
- java代码加密方法,java加密的几种方法
- 马村区网站搭建成本,网站搭建报价
- 沙盒类手机单机游戏,沙盒单机手游推荐
- 学go语言零基础 学go语言零基础难吗