context withcancel概念
context.WithCancel
是 Go 语言标准库 context
包中的一个函数,用于创建一个具有取消功能的上下文(context)。它的主要目的是允许你在需要的时候取消一个长时间运行的任务或多个任务,以确保程序可以优雅地退出或处理超时情况。
用法
ctx, cancel := context.WithCancel(parent)
context.WithCancel
接受一个父上下文(parent
),并返回一个新的上下文ctx
和一个cancel
函数。ctx
是一个新创建的上下文,它会继承父上下文的截止时间(deadline)、值(values)、取消函数等属性。cancel
是一个函数,当调用cancel
函数时,它会取消ctx
及其派生的所有子上下文,导致所有与这些上下文相关的操作都会尽早退出。
context模型
background是根节点,当main使用cancel()方法时,子节点也会结束。
示例
package main
import (
"context"
"fmt"
"time"
)
func print1(ctx context.Context, name string) {
go func(ctx1 context.Context, name1 string) {
for {
select {
case <-ctx.Done():
fmt.Printf("work %s have cancel\n", name1)
return
default:
fmt.Println("running", name1)
time.Sleep(1 * time.Second)
}
}
}(ctx, name+"1")
for {
select {
case <-ctx.Done():
fmt.Printf("work %s have cancel\n", name)
return
default:
fmt.Println("running", name)
time.Sleep(1 * time.Second)
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go print1(ctx, "xzx")
go print1(ctx, "xzj")
time.Sleep(3 * time.Second)
cancel()
time.Sleep(1 * time.Second)
fmt.Println("main canceled")
}
/*output:
running xzj
running xzx
running xzx1
running xzj1
running xzj1
running xzx
running xzx1
running xzj
running xzj
running xzx
running xzj1
running xzx1
work xzj1 have cancel
work xzx have cancel
work xzj have cancel
work xzx1 have cancel
main canceled
*/
上面代码定义了一个print1函数,print1函数里面又定义了一个名叫print2的goroutine,goroutine使用的是print1的print2的ctx,而print1的ctx就是main goroutine的context.Background(),main启动了2个goroutine,所以模型是下面这样
最后main goroutine执行cancel方法,所有的goroutine都执行case <-ctx.Done():,从而结束goroutine。