Golang多線程-線程同步(sync)包-WaitGroup

WaitGroup

  • 其位於較低級的同步包sync
  • WaitGroup為一個結構體;其實例化的用途為等待一組goroutine的集合 完成工作
  • WaitGroup中都有一個counter(計數器)用來記錄等待goroutine的數量

Add

用來設置WaitGroup實例中goroutine counter的數量

  • 在執行goroutine之前先創建對象並加入欲管理的goroutine的數量
  • counter的值為0時代表 等待阻塞的goroutine皆已經被釋放
  • 若是counter的值為負數,則會panic

Wait

等待其它線程完成,並進入阻塞狀態

  • 當實例化的WaitGroup的counter數為0時就會解除當前線程的阻塞狀態

Done

讓實例化的WaitGroup對象數值減 1

  • 其內部代碼就是調用了Add方法只是將其參數(delta)設為 -1
    1
    2
    3
    func (wg *WaitGroup) Done(){
    wg.Add(-1)
    }

Example Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"fmt"
"sync"
)

//創建WaitGroup的實例對象
var wg sync.WaitGroup

func main(){

wg.Add(2)

go PrintNum()
go PrintByte()

fmt.Println("Main Goroutine 將進入阻塞阻塞狀態,等待子goroutine完成工作")
wg.Wait() //main goroutine進入阻塞

fmt.Println("子goroutine工作已全數完成,main goroutine解除阻塞")
}

func PrintNum() {
for i:=0;i<10;i++ {
fmt.Println("PrintNum Gorotine",i)
}
wg.Done() //給WaitGroup的實例化對象counter數值減1,同wg.Add(-1)
}

func PrintByte() {
for i:=0;i<10;i++ {
char := byte(65 + i)
fmt.Println(string(char))
}
wg.Done()
}

Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Main Goroutine 將進入阻塞阻塞狀態,等待子goroutine完成工作
A
B
C
D
E
F
G
H
I
J
PrintNum Gorotine 0
PrintNum Gorotine 1
PrintNum Gorotine 2
PrintNum Gorotine 3
PrintNum Gorotine 4
PrintNum Gorotine 5
PrintNum Gorotine 6
PrintNum Gorotine 7
PrintNum Gorotine 8
PrintNum Gorotine 9
子goroutine工作已全數完成,main goroutine解除阻塞