go - golang ctx取消没有按预期工作
问题描述
func main() {
fmt.Println("Hello, playground")
ctx, cancel := context.WithCancel(context.Background())
func(ctx context.Context) {
for _, i := range []int{1, 2, 3, 4, 5} {
go func(ctx context.Context, i int) {
for {
fmt.Println("go routine#", i)
}
}(ctx, i)
}
}(ctx)
fmt.Println("before cancel num goroutines", runtime.NumGoroutine())
time.Sleep(1 * time.Millisecond)
cancel()
fmt.Println("after cancel num goroutines", runtime.NumGoroutine())
}
输出:-
./ctxCancel
Hello, playground
before cancel num goroutines 6
go routine# 5
go routine# 5
...
after cancel num goroutines 6
go routine# 1
go routine# 1
go routine# 1
go routine# 1
go routine# 2
正如在上面的输出中注意到的那样,我看到调用上下文的取消函数后 numof goroutines 仍然相同。您甚至可以在取消函数调用后看到 goroutine 的打印。我的期望是调用取消函数将终止传递此 ctx 的 go 例程。请帮助我了解上下文取消功能的行为。
解决方案
上下文取消只是关闭一个通道。你的 goroutines 应该检查上下文是否被取消,然后返回。
go func(ctx context.Context, i int) {
for {
select {
case <-ctx.Done():
return
default:
}
fmt.Println("go routine#", i)
}
}(ctx, i)
取消后,您应该等待 goroutines 终止。他们不会立即收到取消通知。
推荐阅读
- arrays - 如何在Lua中的表[表中]中查找所有可能的字符连接
- java - Junit 良好实践:我是否测试运行时错误情况?
- python - 我可以使用 SHAP 值的大小作为异常值检测的阈值吗?
- autocad - 将 AutoCAD 2020 的 ComponentManager.Ribbon 设为空
- c++ - Qwt Plot - 是否可以有多个不同比例的 y 轴?
- .net - ITEXT 7 - Doument Add 方法在.Net Core 中添加段落对象时引发异常
- android - 智能横幅默认文本
- python - google trax 如何输出多类预测,我怎么知道它们属于什么标签?
- .htaccess - 移动到新服务器,使用 https,但 css 和 js 请求是 http
- javascript - API Routes以不同的结构返回数据,我需要返回一个对象数组