7

The full name of sync is synchronization, which means synchronization.
WaitGroup synchronous waiting group is a group of goroutines to wait for execution, and the current goroutine needs to wait for this group of goroutines to be executed before execution.
Here is the definition of WaitGroup:

 type WaitGroup struct {
    //
}

Each WaitGroup has a counter to record the number of goroutines waiting to be executed. The Add method can be used to set the number of goroutines waiting in the synchronous waiting group. Each goroutine will be executed. After execution, the done method will be called to indicate that the value of the counter is -1. At the same time, the wait method will be used to block until all goroutines are executed.
func (wg *WaitGroup) Add(delta int)

  • If the value of the counter is 0, the goroutines blocked during the waiting process will be released
  • If the counter is known to be negative, panic is raised

So in what specific situation and how to use it?
Here is an example:

 package main

import "fmt"

func main() {
    //waitGroup
    go fun1()
    go fun2()
}

func fun1() {
    for i := 1; i < 10; i++ {
        fmt.Println("print A in fun1", i)
    }
}

func fun2() {
    for i := 0; i < 10; i++ {
        fmt.Println("\t fun2 print: ", i)
    }
}

This ends up printing nothing because the main goroutine ends before the two goroutines fun1 and fun2 execute. At this time, you can use WaitGroup.

 package main

import (
    "fmt"
    "sync"
)

//创建同步等待组
var wg sync.WaitGroup

func main() {
    //waitGroup
    wg.Add(2) //设置计数器为2(goroutine的个数)
    go fun1()
    go fun2()
    fmt.Println("main 进入阻塞状态, 需要等待wg的goroutine结束")
    wg.Wait() //表示main goroutine进入阻塞
    fmt.Println("计数器归零 停止阻塞")
}

func fun1() {
    defer wg.Done() //计数器-1
    for i := 1; i < 10; i++ {
        fmt.Println("print A in fun1", i)
    }
}

func fun2() {
    defer wg.Done() //计数器-1
    for i := 0; i < 10; i++ {
        fmt.Println("\t fun2 print: ", i)
    }
}

The result is as follows:

 main 进入阻塞状态, 需要等待wg的goroutine结束
print A in fun1 1
print A in fun1 2
         fun2 print:  0
         fun2 print:  1
         fun2 print:  2
         fun2 print:  3
         fun2 print:  4
print A in fun1 3
print A in fun1 4
print A in fun1 5
print A in fun1 6
print A in fun1 7
print A in fun1 8
print A in fun1 9
         fun2 print:  5
         fun2 print:  6
         fun2 print:  7
         fun2 print:  8
         fun2 print:  9
计数器归零 停止阻塞

The first line of the result shows that both goroutines have been started, and then alternately use the time slice of the CPU.
In addition, if the value of the counter is still greater than 0 when the function is executed, it will cause a deadlock.


In addition, the Go language does not recommend the above writing method, and it is more recommended to use chanel.

Data reference: bilibili


LiberHome
409 声望1.1k 粉丝

有问题 欢迎发邮件 📩 liberhome@163.com