Go 程序从 main 包的 main()
函数开始,在程序启动时,Go 程序就会为 main()
函数创建一个默认的 goroutine
。
所有 goroutine
在 main()
函数结束时会一同结束。
若在启用的goroutine
中不使用WaitGroup
的话会因为main函数已执行完,阻塞的函数与发送信号的函数会一同结束,不能真正实现阻塞的功能。
因此可以使用WaitGroup
来实现阻塞的功能。
如下为不加WaitGroup
时的版本
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
|
package main
import (
"fmt"
"time"
)
var closeCh = make(chan struct{})
func main() {
// var wg sync.WaitGroup
fmt.Println("start main func")
// wg.Add(1)
go func() {
fmt.Println("waiting for signal")
<-closeCh
fmt.Println("got signal.")
// wg.Done()
}()
// wg.Add(1)
go func() {
fmt.Println("preparing for signal:")
for i := 0; i < 3; i++ {
fmt.Println(">>>>")
time.Sleep(time.Second * 1)
}
closeCh <- struct{}{}
fmt.Println("sent signal.")
// wg.Done()
}()
// wg.Wait()
}
|
执行结果
1
|
start main func // 只打印输出了这么一行
|
如下为加WaitGroup
时的版本
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
|
package main
import (
"fmt"
"sync"
"time"
)
var closeCh = make(chan struct{})
func main() {
var wg sync.WaitGroup
fmt.Println("start main func")
wg.Add(1)
go func() {
fmt.Println("waiting for signal")
<-closeCh
fmt.Println("got signal.")
wg.Done()
}()
wg.Add(1)
go func() {
fmt.Println("preparing for signal:")
for i := 0; i < 3; i++ {
fmt.Println(">>>>")
time.Sleep(time.Second * 1)
}
closeCh <- struct{}{}
fmt.Println("sent signal.")
wg.Done()
}()
wg.Wait()
}
|
执行结果:
1
2
3
4
5
6
7
8
|
start main func
preparing for signal:
>>>>
waiting for signal
>>>>
>>>>
got signal.
sent signal.
|
参考:
http://c.biancheng.net/view/93.html