怎么在GOLANG中利用上下文管理关联goroutine

  介绍

这篇文章给大家介绍怎么在GOLANG中利用上下文管理关联goroutine,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

wg :=, sync.WaitGroup {}   defer  wg.Wait ()      wg.Add (1)   go  func (), {   defer 才能;wg.Done ()      ss 才能:=,(os.Signal, 0)   signal.Notify才能(ss, syscall.SIGINT,, syscall.SIGTERM)   for 才能;s :=, ss  {   ,,,fmt.Println (“Got  signal",,)   ,才能打破   ,,}   } ()      wg.Add (1)   go  func (), {   defer 才能;wg.Done ()      svr 才能;:=,,http.Server {, Addr:“: 8080,,,处理程序:nil,,}   fmt.Println才能(svr.ListenAndServe ())   }

很清楚,起了两个goroutine,然后用WaitGroup等待它们退出。如果它们之间没有交互,不互相影响,那真的是蛮简单的,可惜这样是不行的,因为信号的goroutine收到退出信号后,应该通知服务器退出暴。力一点的是直接调用<代码> svr.Close()> wg :=, sync.WaitGroup {}   defer  wg.Wait ()      ctx, cancel :=, context.WithCancel (context.Background ())      wg.Add (1)   go  func (), {   defer 才能;wg.Done ()      ss 才能:=,(chan  os.Signal, 0)   signal.Notify才能(ss, syscall.SIGINT,, syscall.SIGTERM)   select {才能   case 才能;& lt;作用;ctx.Done ():   ,才能返回   case 才能;s :=, & lt;作用;ss:   ,,,fmt.Println (“Got  signal",,)   ,,,取消(),//,取消请求,通知用到ctx的所有goroutine   ,才能返回   ,,}   } ()      wg.Add (1)   go  func (), {   defer 才能;wg.Done ()   defer 才能;取消()      svr 才能;:=,,http.Server {, Addr:“: 8080,,,处理程序:nil,,}      go 才能;func () {   ,,,select  {   ,,,case  & lt;作用;ctx.Done ():   ,,,,,svr.Close ()   ,,,}   ,,}      fmt.Println才能(svr.ListenAndServe ())   }

这个方式可以在新开goroutine时继续使用,譬如新加一个goroutine,里面读写了UDPConn:

wg.Add (1)   go  func (), {   defer 才能;wg.Done ()   defer 才能;取消()      var 才能;conn  * net.UDPConn   err  if 才能,康涅狄格州,=,net.Dial (“udp",,“127.0.0.1:1935");, err  !=, nil  {   ,,,fmt.Println (“Dial  UDP  server 失败了,,err 女儿家,,,呃)   ,才能返回   ,,}      fmt.Println才能(UDPRead (ctx,康涅狄格州))   } ()      时间=UDPRead  func (ctx  context.Context, conn  * net.UDPConn), (err 错误),{   wg 才能;:=,sync.WaitGroup {}   defer 才能;wg.Wait ()      ,,ctx, cancel :=, context.WithCancel (ctx)      wg.Add才能(1)   go 才能;func (), {   ,,,defer  wg.Done ()   ,,,defer 取消()      ,,,for  {   ,,,,,b :=,([]字节,,core.MTUSize)   ,,,,,,,,err  _:=, conn.ReadFromUDP (b)   ,,,,,//,处理UDP包,b(尺寸):   ,,,}   }()才能      select {才能   case 才能;& lt; -ctx.Done ():   ,,,conn.Close ()   ,,}   ,返回   }

如果只是用到HTTP服务器,可以这么写:

func 运行(ctx  contex.Context), {   server 才能;:=,,http.Server {Addr: Addr,,处理程序:,nil}   go 才能;func (), {   ,,,select  {   ,,,case  & lt; -ctx.Done ():   ,,,,,server.Close ()   ,,,}   }()才能      http.HandleFunc才能(“/api",, func (w  http.ResponseWriter, r  * http.Request), {   })才能      fmt.Println才能(server.ListenAndServe ())   }

如果需要提供一个API来让服务器退出,可以这么写:

func 运行(ctx  contex.Context), {   server 才能;:=,,http.Server {Addr: Addr,,处理程序:,nil}      ,,ctx, cancel :=, context.WithCancel (ctx)   http.HandleFunc才能(“/quit",, func (w  http.ResponseWriter, r  * http.Request), {   ,,,取消(),//,使用局部的ctx和取消   })才能      go 才能;func (), {   ,,,select  {   ,,,case  & lt; -ctx.Done ():   ,,,,,server.Close ()   ,,,}   }()才能      fmt.Println才能(server.ListenAndServe ())   }

使用局部的ctx和取消,可以避免取消传入的ctx,只是影响当前的ctx。

怎么在GOLANG中利用上下文管理关联goroutine