go context 控制协成退出
注意:子协成中的select.default: 会重复执行,需要自行确保任务的执行完成
1package main
2
3import (
4 "context"
5 "fmt"
6 "time"
7)
8
9func HandelRequest(ctx context.Context) {
10 go WriteLog(ctx)
11 go WriteDB(ctx)
12 work := false
13 for {
14 select {
15 case <-ctx.Done():
16 fmt.Println("请求处理完毕")
17 return
18 default:
19 if !work {
20 fmt.Println("请求处理中……")
21 work = true
22 time.Sleep(2 * time.Second)
23 // add return, 代表任务执行完成
24 } else {
25 time.Sleep(2 * time.Second)
26 }
27 }
28 }
29}
30func WriteLog(ctx context.Context) {
31 w := false
32 for {
33 select {
34 case <-ctx.Done():
35 fmt.Println("写日志完成")
36 return
37 default:
38 if !w {
39 fmt.Println("写日志中……")
40 w = true
41 time.Sleep(2 * time.Second)
42 // add return, 代表任务执行完成
43 } else {
44 time.Sleep(2 * time.Second)
45 }
46 }
47 }
48}
49func WriteDB(ctx context.Context) {
50 w := false
51 for {
52 select {
53 case <-ctx.Done():
54 fmt.Println("写数据库完成")
55 return
56 default:
57 if !w {
58 fmt.Println("写数据库中……")
59 time.Sleep(2 * time.Second)
60 w = true
61 // add return, 代表任务执行完成
62 } else {
63 time.Sleep(2 * time.Second)
64 }
65 }
66 }
67}
68func main() {
69 //WithCancel
70 ctx, cancel := context.WithCancel(context.Background())
71 go HandelRequest(ctx)
72 time.Sleep(5 * time.Second)
73 fmt.Println("所有子协程都需要结束!")
74 cancel()
75 //Just for test whether sub goroutines exit or not
76 time.Sleep(5 * time.Second)
77
78 //WithTimeout
79 /*ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
80 go HandelRequest(ctx)
81 time.Sleep(10 * time.Second)*/
82
83}
评论