参考文章
问题纠正
之前视频讲过一个知识点,如何设置子协裎超时机制,其实像下面这段代码,主协裎关闭后子协裎是不会停止的:
func TestZ92(t *testing.T) { // 超时时间为1秒的ctx ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second*1)) defer cancel() // 超时的子任务 go func(ctx context.Context) { // 子任务执行3秒 fmt.Println("子协裎任务开始执行!") // Notice 已经在执行的这个任务没有办法立刻退出! time.Sleep(time.Second * 3) fmt.Println("子协裎任务执行完成!") }(ctx) select { case <-ctx.Done(): fmt.Println("主协裎的ctx已经完成!") // case <-time.After(time.Duration(time.Second * 5)): // fmt.Println("timeout!!!") // return } time.Sleep(time.Second * 6) fmt.Println("主协裎关闭!!!") }View Code
打印的结果如下(可以看到,虽然把ctx传进去但是没有用,主协裎由于超时关闭了,子协裎还在执行~):
子协裎任务开始执行! 主协裎的ctx已经完成! 子协裎任务执行完成! 主协裎关闭!!!
可以做如下修改:
func TestZ92(t *testing.T) { // 超时时间为1秒的ctx ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second*1)) defer cancel() // 超时的子任务 go func(ctx context.Context) { // 子任务执行3秒 fmt.Println("子协裎任务开始执行!") // Notice 已经在执行的这个任务没有办法立刻退出! time.Sleep(time.Second * 3) // Notice 在耗时操作后面判断一下,如果ctx已经Done了,就不往下执行了!!! select { case <-ctx.Done(): return } fmt.Println("子协裎任务执行完成!") }(ctx) select { case <-ctx.Done(): fmt.Println("主协裎的ctx已经完成!") // case <-time.After(time.Duration(time.Second * 5)): // fmt.Println("timeout!!!") // return } time.Sleep(time.Second * 6) fmt.Println("主协裎关闭!!!") }
123
123
123
标签:泄漏,goroutine,ctx,golang,任务,context,time,超时,子协 From: https://www.cnblogs.com/paulwhw/p/17003763.html