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}