优雅关闭协程
最后更新于:2022-04-02 02:36:37
[TOC]
## 概述
- 不管是使用 **sync.WaitGroup**,还是 **context.Background** 都可以防止协程泄露
- 都是通过 chan 的关闭来触发退出
## 实例
### sync.WaitGroup 控制一个结构体退出
输出 ``` subtask subtask subtask subtask sub——stop sub——stop stop sub——stop sub——stop sub——stop ``` ### sync.WaitGroup 控制两个结构体退出 第一个结构体也可以采用 chan 的方式去控制退出
### context 控制退出 实例可参考 https://github.com/9b9387/zero
';
main.go
``` package main import ( "fmt" "os" "os/signal" "sync" "time" ) type server struct { quit chan struct{} isrun bool wait sync.WaitGroup } func newServer() *server { return &server{ quit:make(chan struct{}), wait: sync.WaitGroup{}, isrun:true, } } func (s *server) close(){ close(s.quit) s.wait.Wait() } func (s *server) task(){ s.wait.Add(1) defer s.wait.Done() for { select { case <-s.quit: // 退出协程 fmt.Printf("%+v\n", "stop") return default: } fmt.Printf("%+v\n", "task") go s.subtask() time.Sleep(1*time.Second) } } func (s *server) subtask() { s.wait.Add(1) defer s.wait.Done() for { select { case <-s.quit: // 退出协程 fmt.Printf("%+v\n", "sub——stop") return default: } fmt.Printf("%+v\n", "subtask") time.Sleep(1*time.Second) } } func main() { s := newServer() defer s.close() go s.task() sig:=make(chan os.Signal) signal.Notify(sig,os.Interrupt) <-sig } ```输出 ``` subtask subtask subtask subtask sub——stop sub——stop stop sub——stop sub——stop sub——stop ``` ### sync.WaitGroup 控制两个结构体退出 第一个结构体也可以采用 chan 的方式去控制退出
main.go
``` package main import ( "fmt" "os" "os/signal" "sync" "time" ) type Big struct { wait sync.WaitGroup } func (b *Big) run() { for i := 0; i < 10; i++ { b.wait.Add(1) go func(index int) { defer b.wait.Done() s := small{} s.Run(index) }(i) } } func (b *Big) Close() { fmt.Println("ready quit ..") b.wait.Wait() fmt.Println("quit ...") } type small struct { } func (s *small) Run(j int) { for i := 0; i < 5; i++ { fmt.Printf("%+v-%v\n", j, i) time.Sleep(1 * time.Second) } } func main() { var b Big b.run() defer b.Close() s := make(chan os.Signal) signal.Notify(s, os.Kill, os.Interrupt) <-s } ```### context 控制退出 实例可参考 https://github.com/9b9387/zero