思考
我们可以通过 无buffer 的 channel来进行通知,那有没有更简便的方法?
WaitGroup
WaitGroup是什么?
WaitGroup等待一组Goroutine的完成,main goroutine 调用 Add 来设置要等待的 goroutine 的数量。然后每个 goroutine 运行并在完成时调用 Done。同时,Wait 可以用来阻塞,直到所有的 goroutine 都完成
1  | go复制代码type WaitGroup struct {  | 
示例
1  | go复制代码func main() {  | 
问题
- 并发的时候
url的值可能会发生混淆,因为在循环的时候使用的是相同的实例url,当执行downloadFile(url)的时候,url的值可能已经被更改 
如何检测这种情况呢?
go vet
如何解决?
* 启动的时候将当前值绑定给闭包
* 创建一个新的变量- 如何知道启动的goroutine组里边他们的运行情况?是否发生错误了?如何返回错误?假如某一个goroutine发生错误了,如何取消其他goroutine,避免资源的浪费
 - 如何控制超时或者取消
 
errgroup
errgroup是什么?
提供同步,错误传播,一组gorouines的context的取消,致力于解决通用任务的子任务们
函数签名
1  | go复制代码// A Group is a collection of goroutines working on subtasks that are part of  | 
func WithContext
1  | go复制代码func WithContext(ctx context.Context ) (*Group , context.Context )  | 
WithContext 返回一个新的 Group 和一个从 ctx 派生的关联上下文。会创建一个带取消的Group
派生的 Context 在第一次传递给 Go 的函数返回非 nil 错误时或第一次 Wait 返回时被取消,以先发生者为准。
func (*Group) Go
1  | go复制代码func (g * Group ) Go(f func() error)  | 
Go 在一个新的 goroutine 中调用输入的函数。
第一次调用返回非nil 错误并且会执行取消逻辑;它的错误将由 Wait 返回。
func (*Group) Wait
1  | go复制代码func (g * Group ) Wait() error  | 
Wait 阻塞,直到所有来自 Go 方法的函数调用都返回,然后从它们返回第一个非 nil 错误(如果有)。
示例
传播错误
1  | go复制代码func main() {  | 
取消其他子任务
1  | go复制代码func main() {  | 
总结
- 如果多个
Goroutine出现错误,只会获取到第一个出错的Goroutine的错误信息,其他出错的Goroutine的错误信息将不会被感知到。 errgroup.Group在出现错误或者等待结束后都会调用Context对象 的cancel方法同步取消信号
参考链接
本文转载自: 掘金