golang ctx取消没有按预期工作

Posted

技术标签:

【中文标题】golang ctx取消没有按预期工作【英文标题】:golang ctx cancel not working as expected 【发布时间】:2021-07-12 08:17:57 【问题描述】:
func main() 
    fmt.Println("Hello, playground")
    ctx, cancel := context.WithCancel(context.Background())
    func(ctx context.Context) 

        for _, i := range []int1, 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 例程。请帮我理解上下文取消函数的行为。

【问题讨论】:

sohamkamani.com/golang/… 上下文和 goroutine 是不相关的概念,取消第一个对 goroutine 没有任何作用。 【参考方案1】:

上下文取消只是关闭一个通道。你的 goroutine 应该检查上下文是否被取消,然后返回。

            go func(ctx context.Context, i int) 
                for 
                    select 
                        case <-ctx.Done():
                           return
                        default:
                     
                    fmt.Println("go routine#", i)
                

            (ctx, i)

取消后,您应该等待 goroutines 终止。他们不会立即收到取消通知。

【讨论】:

谢谢。抱歉这个天真的问题。刚接触 golang 并尝试学习它。

以上是关于golang ctx取消没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

golang 类型转换不能按(我)预期的那样工作

golang 调用 php7

golang macaron解决跨域

golang macaron解决跨域

Golang取消sql正在进行的操作

Golang fsnotify 在 Windows 上为同一个文件发送多个事件