百木园-与人分享,
就是让自己快乐。

Golang WaitGroup源码解析

Go WaitGroup源码解析

结构体

type WaitGroup struct {
 noCopy noCopy
 state1 [3]uint32
}

其中state1代表三个字段:counter, waiter, sema

  • counter:计数器,每次经过wg.Add(X)或者wg.Done()后的值
  • waiter:调用wg.Wait()的数量,也就是等待者的数量
  • sema:信号量,用于换醒Wait()函数

退出WaitGroup的条件

  • counter == 0

Add(n)

  1. 更新counter的值。counter += n
  2. 判断当前counter > 0 || waiter == 0,满足条件,说明当前还有groutine没有执行完,直接返回。
  3. 走到这一步,说明counter == 0 && waiter != 0,说明groutine全部执行了Done()方法,换醒执行了wg.Wait()的协程,将state设置成0,返回。

Wait()

  1. 循环判断下面操作
  2. 判断counter == 0,如果为true,说明groutine已经全部执行了Done()方法,Wait Done。
  3. 此时counter != 0,说明需要阻塞当前协程的执行,执行下面的CAS判断
  4. CAS判断wg.state有没有被改变,没有则更新wg.state为1,当前协程进入sleep状态,等待信号量换醒。换醒后继续循环判断,此时counter==0,直接wait done。
  5. CAS判断wg.state有没有被改变,则继续循环判断。继续判断counter

Done()

Done 的实现就是 Add. 只不过我们常规用法 wg.Add(1) 是加 1 ,wg.Done() 是减 1,即 wg.Done() 可以用 wg.Add(-1) 来代替。尽管我们知道 wg.Add 可以传递负数当 wg.Done 使用,但是还是别这么用。


来源:https://www.cnblogs.com/xiaofua/p/16138840.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Golang WaitGroup源码解析

相关推荐

  • 暂无文章