试图了解 go 上下文取消将如何中止后续代码的执行
实验细节:
- main func 有一个超时的上下文
2sec
- main func
sum
在单独的 go-routine 中调用另一个 func - 它1sec
为 test-run-1 和4sec
为 test-run-2休眠 - 让 main sleep
3sec
让 spun go-routine 完成执行
package main
import (
"context"
"fmt"
"log"
"time"
)
func main() {
c := context.Background()
childCtx, cancel := context.WithTimeout(c, 2*time.Second)
defer cancel()
ch := make(chan int, 1)
go sum(5, 6, ch)
var msg string
select {
case <-childCtx.Done():
msg = "return from ctx done channel"
case res := <-ch:
msg = fmt.Sprintf("return from go routine: %v", res)
}
log.Print(msg)
time.Sleep(3 * time.Second) //sleeping here to test if go-routine is still running
}
func sum(x int, y int, c chan<- int) {
time.Sleep(1 * time.Second)
//testcase-1: sleep - 1s
//testcase-2: sleep - 4s
result := x + y
log.Printf("print from sum fn: %v", result)
c <- result
}
testcase-1 的响应:睡眠总和功能 1 秒:
2021/04/12 01:06:58 print from sum fn: 11
2021/04/12 01:06:58 return from go routine: 11
testcase-2 的响应:睡眠总和功能 4 秒:
2021/04/12 01:08:25 return from ctx done channel
2021/04/12 01:08:27 print from sum fn: 11
在 testcase-2 中,当 sum func 休眠 4 秒时,上下文已经在 2 秒后被超时取消,为什么它仍然在 diff go-routine 中执行 sum func 并打印print from sum fn: 1
?
来自文档:取消此上下文会释放与其关联的资源。
我的假设是所有计算将在 2 秒后立即中止,包括旋转的 go-routine
让我知道如何正确执行此操作,提前谢谢