Golang Waitgroup Source Analysis

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Sync for Golang 1.9. Waitgroup for analysis, the same as the Golang 1.10, except panic that it will be changed to throw something other than the others.
Source code location: sync\waitgroup.go .

Structural body

type WaitGroup struct {    noCopy noCopy  // noCopy可以嵌入到结构中,在第一次使用后不可复制,使用go vet作为检测使用    // 位值:高32位是计数器,低32位是goroution等待计数。    // 64位的原子操作需要64位的对齐,但是32位。编译器不能确保它,所以分配了12个byte对齐的8个byte作为状态。    state1 [12]byte // byte=uint8范围:0~255,只取前8个元素。转为2进制:0000 0000,0000 0000... ...0000 0000    sema   uint32   // 信号量,用于唤醒goroution}

I do not know whether people like me, whether it is the use of Java Countdownlatch or Golang Waitgroup, will be questioned, can be loaded with multiple threads | co-process wait? After reading the source can answer, can be installed

1111 1111 1111 ... 1111\________32___________/

2^32 a lot of spicy! So you don't have to worry about being blown up in a single case.

Function

The following code has removed the race code that is not related to the core code.

Add

Add or decrease the number of waiting goroutine.

Add the delta, which may be negative, to the Waitgroup counter.

    • If the counter becomes 0, all blocked Goroutines will be released.
    • If the counter becomes negative, it increases panic.
  func (WG *waitgroup) Add (delta int) {//Gets the decimal value of the binary corresponding to the elements in the wg.state1 array statep: = Wg.state ()//high 32 bits is Counter state: = Atomic. AddUint64 (Statep, UInt64 (delta) <<32)//Get counter V: = Int32 (State >> +) W: = UInt32 (state)//counter is negative , reported panic if v < 0 {Panic ("sync:negative waitgroup Counter")}//Add and wait for concurrent calls, reported panic if w! = 0 &&A mp     Delta > 0 && v = = Int32 (Delta) {Panic ("Sync:waitgroup Misuse:add called concurrently with Wait")} The counter is added successfully if v > 0 | |    W = = 0 {return}//When waiting for counter > 0 o'clock, while Goroutine is set to 0. There can be no simultaneous state mutation at this time://-The increase cannot occur simultaneously with the wait,//-if the counter counter = = 0, the wait counter is no longer incremented if *statep! = states {Panic ("Sync:    Waitgroup Misuse:add called concurrently with Wait ")}/Reset waiters count to 0. *statep = 0 for; W! = 0; w--{//is intended as a simple wakeup primitive for simultaneous use. True for Wake queue first Goroutine runtime_semrelease (&wg.sema, False)}}  
// unsafe.Pointer其实就是类似C的void *,在golang中是用于各种指针相互转换的桥梁。// uintptr是golang的内置类型,是能存储指针的整型,uintptr的底层类型是int,它和unsafe.Pointer可相互转换。// uintptr和unsafe.Pointer的区别就是:unsafe.Pointer只是单纯的通用指针类型,用于转换不同类型指针,它不可以参与指针运算;// 而uintptr是用于指针运算的,GC 不把 uintptr 当指针,也就是说 uintptr 无法持有对象,uintptr类型的目标会被回收。// state()函数可以获取到wg.state1数组中元素组成的二进制对应的十进制的值func (wg *WaitGroup) state() *uint64 {    if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {        return (*uint64)(unsafe.Pointer(&wg.state1))    } else {        return (*uint64)(unsafe.Pointer(&wg.state1[4]))    }}

Done

Equivalent to add (-1).

func (wg *WaitGroup) Done() {    // 计数器减一    wg.Add(-1)}

Wait

Execution is blocked until all the Waitgroup number becomes 0.

func (wg *WaitGroup) Wait() {    // 获取到wg.state1数组中元素组成的二进制对应的十进制的值    statep := wg.state()    // cas算法    for {        state := atomic.LoadUint64(statep)        // 高32位是计数器        v := int32(state >> 32)        w := uint32(state)        // 计数器为0,结束等待        if v == 0 {            // Counter is 0, no need to wait.            return        }        // 增加等待goroution计数,对低32位加1,不需要移位        if atomic.CompareAndSwapUint64(statep, state, state+1) {            // 目的是作为一个简单的sleep原语,以供同步使用            runtime_Semacquire(&wg.sema)            if *statep != 0 {                panic("sync: WaitGroup is reused before previous Wait has returned")            }            return        }    }}

Precautions for use

    1. Waitgroup cannot guarantee multiple Goroutine execution order
    2. Waitgroup cannot specify a fixed number of goroutine
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.