在看NSQ源码时看到封装了waitgroup方法,很实用,于是网上找了一篇文章,顺带整个流程熟悉一遍
golang的协程使用非常方便,但是为了确保协程能在主程序退出之前确保执行,会使用各种手段。
笨点的time大法:
package main
import (
"fmt"
"time"
)
func foo() {
fmt.Println("foo")
}
func main() {
go foo()
time.Sleep(time.Second)
}
稍微好点的通道阻塞
package main
import "fmt"
var channel = make(chan int)
func foo() {
fmt.Println("fooooo")
// 传递一个完成信号
channel<-1
}
func main() {
go foo()
// 读取 完成操作
<-channel
}
聪明点的,使用sync.WaitGroup
package main
import (
"fmt"
"sync"
)
func foo() {
fmt.Println("fooo")
}
func foo1() {
fmt.Println("fooo11111")
}
func foo2() {
fmt.Println("fooo222222")
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
foo()
wg.Done()
}()
wg.Add(1)
go func() {
foo1()
wg.Done()
}()
wg.Add(1)
go func() {
foo2()
wg.Done()
}()
fmt.Println("main")
wg.Wait()
}
没有了全局变量,代码这样写的代码看起来很臃肿,继续优化一下
封装WaitGroup Wrapper
/nsq/xiaoliang/util/wg.go
package util
import "sync"
type WaitGroupWrapper struct {
sync.WaitGroup
}
func (wg *WaitGroupWrapper) Wrap(f func()) {
wg.Add(1)
go func() {
f()
wg.Done()
}()
}
封装waitgroup代码
/nsq/xiaoliang/xiaoliang.go
package main
import (
"fmt"
"github.com/nsqio/nsq/xiaoliang/util"
)
func main() {
var w util.WaitGroupWrapper
w.Wrap(func() {
fmt.Println("fooo")
})
w.Wrap(func() {
fmt.Println("foo1111")
})
w.Wrap(func() {
fmt.Println("foo2222")
})
w.Wait()
}
封装后的代码,简洁了好多