当一个任务需要多个线程一起去完成时,主线程不能退出,主线程一旦退出,进程结束,所有的线程也被销毁了。如果可以用一个很粗糙的方式让主线程等待所有的工作线程都结束后在退出,参考代码:
package main
import "time"
func main() {
for i := 1; i < 10; i++ {
go func() {
// do something...
}()
}
time.Sleep(10 * time.Second)
}
通过估算,我们让主线程sleep10秒钟后退出,这是一种非常ugly的方式。Go语言提供了一个很优雅的方式来实现相同的功能。参考代码:
package main
import "sync"
func main() {
var wg sync.WaitGroup
wg.Add(10)
for i := 1; i < 10; i++ {
go func() {
// do something...
wg.Done()
}()
}
wg.Wait()
}
还有一个稍微麻烦点的实现方式,使用Go的channel,参考代码:
package main
import "fmt"
func main() {
done := make(chan bool)
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i)
done <- true
}(i)
}
for i := 0; i < 10; i++ {
<-done
}
}
一个编程技巧,来自nsq的源代码:
package main
import (
"fmt"
"sync"
)
type WaitGroupWrapper struct {
sync.WaitGroup
}
func (w *WaitGroupWrapper) Wrapper(cb func()) {
w.Add(1)
go func() {
cb()
w.Done()
}()
w.Wait()
}
type Person struct {
Wrapper WaitGroupWrapper
Name string
Age int
}
func main() {
var p Person
exitFunc := func() {
fmt.Println("exit func")
}
p.Wrapper.Wrapper(exitFunc)
p.Wrapper.Wrapper(exitFunc)
}