sync.WaitGroup (package sync)
-
func (wg *WaitGroup) Add(delta int)
-
func (wg *WaitGroup) Done()
-
func (wg *WaitGroup) Wait()
//@brief: golang并发控制
//@note: WaitGroup和Context
//@author: richard
package main
import (
"fmt"
"sync"
)
type httpPkg struct{}
var http httpPkg
func (httpPkg) Get(url string) {
fmt.Println(url)
}
//WaitGroup
//场景: A/B/C 异步执行,D需要在A/B/C都完成后才被执行
// A----->}
// B----->}--->D--->
// C----->}
func main() {
var gwg sync.WaitGroup
var urls = []string{
"http://1.org",
"http://2.org",
"http://3.org",
}
fmt.Println("all start")
for i := range urls {
gwg.Add(1)
go func(lwg *sync.WaitGroup, url string) {
defer lwg.Done()
http.Get(url)
}(&gwg, urls[i])
}
// Wait for all HTTP fetches to complete.
gwg.Wait()
fmt.Println("all done")
}
///结果//
all start
http://3.org
http://1.org
http://2.org
all done
Context (package context)
-
func Background() Context
-
func TODO() Context
-
func WithValue(parent Context, key, val interface{}) Context
//@brief: golang并发控制
//@note: WaitGroup和Context
//@author: richard
package main
import (
"context"
"fmt"
"time"
)
//Context 主动的通知goroutine执行操作
//场景: A执行启动B/C/D协程, C启动了E/F协程,在某种条件下需要停止E/F。
// {B--->
// A--->{C--->--->{E--->
// { {F--->
// {D--->
//
func main() {
//@note: cancel
ctx, cancel := context.WithCancel(context.Background())
go test(ctx,"01")
go test(ctx,"02")
go test(ctx,"03")
time.Sleep(10 * time.Second)
cancel()
time.Sleep(10 * time.Second)
}
func test(ctx context.Context, name string) {
for {
select {
case <-ctx.Done():
fmt.Println(name,"exit")
return
default:
fmt.Println(name,"running")
time.Sleep(time.Second)
}
}
}
///结果//
03 running
02 running
01 running
03 running
01 running
02 running
02 running
01 running
03 running
01 exit
03 exit
02 exit
Context 使用原则
-
不用Context放在结构体, 应该参数的方式传递
-
不要什么都使用这个传递,Context的Value相关方法应传递数据,
-
Context作为第一参数 ctx
-
不要传递nil。context.TODO
-
Context线程安全
sync.WaitGroup
-
goroutine间执行无序
-
[sync.WaitGroup 踩坑样本]
-
https://liudanking.com/golang/golang-waitgroup-usage/
-
参考文档
-
https://draveness.me/golang/concurrency/golang-context.html
-
https://www.flysnow.org/2017/05/12/go-in-action-go-context.html