解决Golang父协程退出子协程不退出
情况如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| fmt.Println("main函数开始...") go func() { fmt.Println("父协程开始...") go func() { for { fmt.Println("子协程执行中...") timer := time.NewTimer(time.Second * 2) <-timer.C } }() time.Sleep(time.Second*5) fmt.Println("父协程退出...") }() time.Sleep(time.Second*10) fmt.Println("main函数退出")
|
打印结果
1 2 3 4 5 6 7 8 9
| main函数开始... 父协程开始... 子协程执行中... 子协程执行中... 子协程执行中... 父协程退出... 子协程执行中... 子协程执行中... main函数退出
|
解决方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| fmt.Println("main 函数开始...") go func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() fmt.Println("父协程开始...") go func(ctx context.Context) { for { for { select { case <-ctx.Done(): fmt.Println("子协程接受停止信号...") return default: fmt.Println("子协程执行中...") timer := time.NewTimer(time.Second * 2) <-timer.C } } } }(ctx) time.Sleep(time.Second*5) fmt.Println("父协程退出...") }() time.Sleep(time.Second*10) fmt.Println("main函数退出")
|
执行结果如下:
1 2 3 4 5 6 7 8
| main函数开始... 父协程开始... 子协程执行中... 子协程执行中... 子协程执行中... 父协程退出... 子协程接受停止信号... main 函数 退出
|
结论
上述执行后发现,控制台打印了err和父亲协程退出,但是程序依旧在打印子协程。由此得知协程无父子关系,即在父协程开启新的协程,若父协程退出,不影响子协程。