Golang并发控制WaitGroup和Context

sync.WaitGroup (package sync)

  •     func (wg *WaitGroup) Add(delta int)

  •     func (wg *WaitGroup) Done()

  •     func (wg *WaitGroup) Wait()

//@brief:  golang并发控制//@note:   WaitGroup和Context//@author: richardpackage mainimport ("fmt""sync")type httpPkg struct{}var  http httpPkgfunc (httpPkg) Get(url string) {  fmt.Println(url)}//WaitGroup//场景: A/B/C 异步执行,D需要在A/B/C都完成后才被执行//  A----->}//  B----->}--->D--->//  C----->}func main() {var gwg sync.WaitGroupvar 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 starthttp://3.orghttp://1.orghttp://2.orgall done

Context (package context)

  • func Background() Context

  • func TODO() Context

  • func WithValue(parent Context, key, val interface{}) Context

//@brief:  golang并发控制//@note:   WaitGroup和Context//@author: richardpackage mainimport (  "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 running02 running01 running03 running01 running02 running02 running01 running03 running01 exit03 exit02 exit

Context 使用原则

  • 不用Context放在结构体, 应该参数的方式传递

  • 不要什么都使用这个传递,Context的Value相关方法应传递数据,

  • Context作为第一参数 ctx

  • 不要传递nil。context.TODO

  • Context线程安全

sync.WaitGroup

  • goroutine间执行无序

  • [sync.WaitGroup 踩坑样本] 

    • https://liudanking.com/golang/golang-waitgroup-usage/ 

参考文档

  1. https://draveness.me/golang/concurrency/golang-context.html

  2. https://www.flysnow.org/2017/05/12/go-in-action-go-context.html

 

你可能感兴趣的:(golang)