优雅结束goroutine的几种方法

 

运行完直接结束

1 func Routine1() {
2     fmt.Println("Hello go!")
3 }
4 
5 func TestRoutine1(t *testing.T) {
6     go Routine1()
7     fmt.Println("Hello world!")
8 }

 

等待协程运行完成后结束

 1 func Routine2(wg *sync.WaitGroup) {
 2     fmt.Println("Hello go!")
 3     time.Sleep(2*time.Second)
 4     wg.Done()
 5 }
 6 
 7 func TestRoutine2(t *testing.T) {
 8     var wg sync.WaitGroup
 9     wg.Add(1)
10     go Routine2(&wg)
11 
12     fmt.Println("Hello world!")
13     wg.Wait()
14     fmt.Println("Routine finished!")
15 }

 

发送chan信息结束协程运行

 1 func Routine3(stop chan bool) {
 2     for {
 3         select {
 4         case <-stop:
 5             fmt.Println("Routine be stop  ped ..")
 6             return
 7         default:
 8             fmt.Println("Goroutine running ...")
 9             time.Sleep(2 * time.Second)
10         }
11     }
12 }
13 
14 func TestRoutine3(t *testing.T) {
15     stop := make(chan bool)
16     go Routine3(stop)
17 
18     fmt.Println("Hello world!")
19     time.Sleep(10 * time.Second)
20     stop <-true
21     fmt.Println("Routine finished!")
22 }

 

关闭chan通知协程结束运行

 1 func Routine4(info chan int) {
 2     for {
 3         select {
 4         case info, ch_closed := <-info:
 5             if ch_closed == false {
 6                 fmt.Println("Routine be stopped ..")
 7                 return
 8             }
 9             fmt.Println("Routine recv info .." + strconv.Itoa(info))
10         default:
11             fmt.Println("Goroutine running ...")
12             time.Sleep(2 * time.Second)
13         }
14     }
15 }
16 
17 func TestRoutine4(t *testing.T) {
18     info := make(chan int)
19     go Routine4(info)
20 
21     fmt.Println("Hello world!")
22     info <- 1
23     time.Sleep(2 * time.Second)
24     info <- 2
25     time.Sleep(2 * time.Second)
26     info <- 3
27     time.Sleep(2 * time.Second)
28     close(info)
29     time.Sleep(4 * time.Second)
30     fmt.Println("Routine finished!")
31 }

 

通过context通知协程结束

 1 func Routine5(ctx context.Context) {
 2     for {
 3         select {
 4         case <- ctx.Done():
 5             fmt.Println("Routine be stopped...")
 6             return
 7         default:
 8             fmt.Println("Goroutine running ...")
 9             time.Sleep(1 * time.Second)
10         }
11     }
12 }
13 
14 func TestRoutine5(t *testing.T) {
15     ctx, cancel := context.WithCancel(context.Background())
16 
17     go Routine5(ctx)
18 
19     fmt.Println("Hello world!")
20     time.Sleep(2 * time.Second)
21     cancel()
22     time.Sleep(2 * time.Second)
23     fmt.Println("Routine finished!")
24 }

 

 

参考:

4.9 理解 Go 语言中的 Context

posted @ 2020-10-18 23:19  luobote11  阅读(352)  评论(0)    收藏  举报