Synchronous waiting group WaitGroup in Go language

    In the sync package of the Go language, basic synchronization units such as mutex locks are provided. Except for the Once and WaitGroup types, most of them are suitable for low-level program threads, and it is better to use channel communication for high-level synchronization.
    We can use the wait() method in WaitGroup to block the main thread until the other child threads or coroutines have finished running, and then return to the main thread.

WaitGroup synchronization waiting group

type WaitGroup struct {
    noCopy noCopy
    state1 [12]byte
    sema uint32
}

    WaitGroup is used to wait for the end of a group of threads or coroutines . Thread calls the Add method to set the number of threads that should wait. Each waiting thread should call the Done method at the end. At the same time, the main thread can call the Wait method to block itself, wait for the thread declared in the Add() method to run to the end, and then return to the main thread.

Methods in WaitGroup

  • func (wg *WaitGroup) Add(delta int)
    Add method adds delta to the internal count, delta can be a negative number; if the internal counter becomes 0, all threads waiting in the Wait method block will be released; if the counter is less than 0, Method panic. Note that the call with Add plus a positive number should be used before Wait, otherwise Wait may only wait for a few threads. Generally speaking, the Add() method should be called before creating a new thread or other events that should be waited for.
  • func (wg *WaitGroup) Done() The
    Done method reduces the value of the WaitGroup counter and should be executed at the end of the thread.
  • func (wg *WaitGroup) Wait() The
    Wait method blocks until the WaitGroup counter is reduced to 0.

    Case 1. WaitGroup blocks the main function through wait() to run 3 sub-coroutines.
//myWaitGroupDes.go

// myWatiGroupDes project main.go
package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

func printNumA(wg *sync.WaitGroup) {
	k := 0
	for i := 11; i <= 20; i += 2 {
		fmt.Printf("子协程A[%d]= %d \n", k, i)
		time.Sleep(time.Duration(rand.Intn(1000)))
		k++
	}
	wg.Done() //计算器减1
}

func printNumB(wg *sync.WaitGroup) {
	k := 0
	for i := 22; i <= 30; i += 2 {
		fmt.Printf("子协程B[%d]= %d \n", k, i)
		time.Sleep(time.Duration(rand.Intn(1000)))
		k++
	}
	wg.Done() //计算器减1
}

func printNumC(wg *sync.WaitGroup) {
	k := 0
	for i := 'a'; i <= 'e'; i++ {
		fmt.Printf("子协程C[%d]= %c \n", k, i)
		time.Sleep(time.Duration(rand.Intn(1000)))
		k++
	}
	wg.Done() //计算器减1
}

func main() {
	var wg sync.WaitGroup
	fmt.Printf("%T\n", wg)
	fmt.Println(wg)
	wg.Add(3)
	rand.Seed(time.Now().UnixNano())

	go printNumA(&wg)
	go printNumB(&wg)
	go printNumC(&wg)

	wg.Wait()
	fmt.Println("main解除阻塞,main is over...")
}


    The effect is as follows:

Figure (1) Block the main thread to run 3 sub-coroutines

Guess you like

Origin blog.csdn.net/sanqima/article/details/108919758