在看NSQ源碼時看到封裝了waitgroup方法,很實用,于是網上找了一篇文章,順帶整個流程熟悉一遍
golang的協(xié)程使用非常方便,但是為了確保協(xié)程能在主程序退出之前確保執(zhí)行,會使用各種手段。
笨點的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()
}
沒有了全局變量,代碼這樣寫的代碼看起來很臃腫,繼續(xù)優(yōu)化一下
封裝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()
}
封裝后的代碼,簡潔了好多