golang的协程使用非常方便,但为了确保协程能够在主程序退出之前确保执行,会采用各种手段。
笨点的time大法:
func foo(){
//do something
}
func main(){
go foo()
//do anotherthing
time.Sleep(time.Second)//还真不知道foo运行多久,只能靠猜
}
稍微好点的通道阻塞:
var signalchan=make(chan int,0) //阻塞通道
func foo(){
//do something
signalchan<-1 //传递一个完成信号
}
func main(){
go foo()
//do anotherthing
<-signalchan
}
再聪明点的,使用sync.WaitGroup
代码可以这样写:
func foo(){
//do something
}
func main(){
var w sync.WaitGroup
w.Add(1)
go func(){
foo()
w.Done()
}
//do anotherthing
w.Wait()
虽然没有了全局变量,但感觉代码多了,感觉不清爽,能够优化呢。
WaitGroup Wrapper封装
代码参考如下:
package waitgroup
import (
"sync"
)
type WaitGroupWrapper struct {
sync.WaitGroup
}
func (w *WaitGroupWrapper) Wrap(f func()) {
w.Add(1) //Add必须在go协程外
go func() {
f()
w.Done()
}()
}
这样,之前的代码就可以简化为:
func main(){
var w WaitGroupWrapper
w.Wrap(foo) //四行变成1行
... // do otherthing
w.wait()
}