使用`WithCancel`的`go context`需要涉及以下步骤:
1. 创建一个根context(即没有父级context的context),可以使用`context.Background()`函数来创建。这个根context表明程序的整个生命周期所涉及的context。
2. 使用`context.WithCancel(parent)`函数从根context或其他已有的context中创建一个新的context,并返回新的context和一个cancel函数。这个新的context将继承父级context的属性。
3. 用go协程启动一个函数,函数接收一个context类型的参数,并在函数内部进行可取消的操作,可以使用`ctx.Done()`来检测context是否已经被取消,如果被取消,则停止操作。
4. 在主函数中,使用cancel函数来取消这个context。调用这个函数后,所有基于这个context的子孙协程都将被取消,从而终止它们的操作。
下面是一个使用WithCancel的go context的示例代码:
“`go
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 在程序结束时调用cancel以确保释放资源
// 启动协程
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("已经取消了")
return
default:
fmt.Println("正在进行可取消操作")
time.Sleep(time.Second * 1)
}
}
}(ctx)
// 模拟程序运行
time.Sleep(time.Second * 5)
fmt.Println("已经取消操作")
cancel()
time.Sleep(time.Second)
}
“`
在这个例子中,我们先使用`context.Background()`创建了一个根context,然后使用`context.WithCancel`从根context中创建了一个新的context和一个用于取消这个context的cancel函数。接着我们启动了一个协程,并将创建的新context传递给它,协程在内部进行了可取消的操作。在主函数中,我们等待一段时间,然后使用cancel函数取消了这个context,协程也因此停止了操作。最后我们再等待一段时间,以确保程序正常退出。