Go并发(五):WaitGroup

Stella981
• 阅读 512

本篇其实是Go并发编程的补充篇章,只是用来介绍WaitGroup的使用介绍。

对于Go的并发编程来说,主协程需要知道其他的协程何时结束。通常我们的做法是采用channel的方式来控制,这种做法很好,可以参见我的另外一个帖子(Go并发之channel篇:https://mp.weixin.qq.com/s/PIb-gGBootc6581pHhi5ew)。但是对于一些简单的协程控制来说,channel显得有些大材小用,而WaitGroup就可以派上用场了。

一、WaitGroup定义

WaitGroup是Go pkg中sync 包里的内容:https://golang.org/pkg/sync/,一个 WaitGroup 会等待一系列 goroutine 直到它们全部运行完毕为止。主 goroutine 通过调用 Add 方法来设置需要等待的 goroutine 数量, 而每个运行的 goroutine 则在它们运行完毕时调用 Done 方法。与此同时, 调用 Wait 方法可以阻塞直到所有 goroutine 都运行完毕为止。

1.主协程对其他协程什么都不处理的例子:

Go并发(五):WaitGroup

通过上面的输出可以看出,主协程并没有等待其他协程的结束,就自己退出了,所以看不到关于其他协程的任何打印。

2.主协程通过超时机制来等待其他协程结束的例子:

Go并发(五):WaitGroup

在主协程中新加了超时1s来等待其他协程的结束,通过打印可以看出来,其他协程已经运行并结束。

3.使用wg的例子:

Go并发(五):WaitGroup

通过打印信息可以看到,主协程通过wg.Wait()来判断计数器有没有变为0,来判断其他的协程有没有结束,在主协程检测到wg的计数器变为0之后,便知道其他协程都已经结束了。

二、WaitGroup中的API介绍

1. (*WaitGroup) Add 方法

func(wg*WaitGroup)Add(delta int) 

delta可以为正数,也可以为负数,在wg对应的计数器没有变为0之前delta可以为负数,但是切记不要让wg计数器变为负数,因为一旦变为负数,便会panic。

通常Add在协程启动之前使用。

2. (*WaitGroup) Done 方法

func(wg*WaitGroup)Done() 

对wg计数器进行减1操作。

通常Done在协程执行结束的时候使用。

3.(*WaitGroup) Wait 方法

func(wg*WaitGroup)Wait()

阻塞直至 WaitGroup 计数器的值为 0 。

通常在主协程中使用,用来等待其他的协程结束。


参考文献:

sync 的pkg包:https://golang.org/pkg/sync/


欢迎关注公众号:灰子学技术

Go并发(五):WaitGroup

本文分享自微信公众号 - 灰子学技术(huizixueguoxue)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
HelloWorld官方 HelloWorld官方
3年前
Go Context 并发编程简明教程
1为什么需要ContextWaitGroup和信道(channel)是常见的2种并发控制的方式。如果并发启动了多个子协程,需要等待所有的子协程完成任务,WaitGroup非常适合于这类场景,例如下面的例子:varwgsync.WaitGroupfuncdoTask(nint){time.Sleep(time.Durat
GO语言协程的理解
以下内容大部分摘自许世伟的《GO语言核心编程》最近面试,在自己的简历上写了简单会一些GO语言。结果被面试官问了GO语言goroutine的原理。自己看倒是看过,时间长了又给忘了。特此写下此文以长记性。协程:协程本质上是一种用户态线程,不需要操作系统来进行抢占式调度,并且在真正的实现中寄存于线程中,因此系统开销极小,可以有效的提高线程任务的并发性,而避
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Gevent简明教程
1、前述进程线程协程异步并发编程(不是并行)目前有四种方式:多进程、多线程、协程和异步。多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库多线程编程python中有Thread和threading异步编程在linux下主要有三种实现selec
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
Go 并发
Go并发并发指的是同时处理多个任务的能力。并行指的是并行处理多个任务的能力。并行不一定加快运行速度,因为并行组件之间可能需要互相通信。Go中使用协程,信道来处理并发。协程Go中主要通过协程实现并发。协程是与其他函数或方法一起并发运行的函数或方法,协程可以看作是轻量级线程,但是创建成本更小,我们经常
Wesley13 Wesley13
2年前
Go 中的并发和并行
并行是指同一时间做多件事情,并发是指同一时间具有做多件事情的能力。在很多情况下,并发的效果比并行好,因为操作系统的硬件资源和总资源是很少而且固定的,不能无限去扩张。Go语言设计的时候应该也是推崇这种使用较少资源做更多事情的哲学。并发执行Go语言中可以使用系统功能设置可以使用的物理处理器(核),如果设置为1的话,所有的协程会在一个核上
Easter79 Easter79
2年前
Swoole2.0内置协程并发测试
Swoole2.0是一个革命性的版本,它内置了协程的支持。与Go语言协程不同,Swoole协程完全不需要开发者添加任何额外的关键词,直接以过去最传统的同步阻塞模式编写代码,底层自动进行协程调度实现异步IO。使并发编程变得非常简单。最新的版本中,内置协程已支持PHP7,同时兼具了性能和并发能力,Swoole的强大超乎想象。本文基于Github最新的Sw
Stella981 Stella981
2年前
Golang学习笔记:goroutine
1.goroutinegoroutine是go语言的并发体。在go语言里面能使用go关键字来实现并发。gofunc()1.1概念介绍goroutine本质上是协程,我刚刚学习的时候就粗略地认为goroutine是线程,直到最近才开始搞明白goroutine的基本概念。<fon