我一直在阅读一些关于使用 golang 的 context 包的文章。我最近在博客中看到了以下文章:http: //p.agnihotry.com/post/understanding_the_context_package_in_golang/
该文章对 go 中的上下文取消功能进行了以下说明:
“如果你愿意,你可以传递取消函数,但是,强烈不建议这样做。这可能导致取消的调用者没有意识到取消上下文可能会对下游产生什么影响。可能还有其他派生的上下文这可能会导致程序以意想不到的方式运行。简而言之,永远不要绕过取消函数。
但是,如果我希望激活父 context.Done() 通道,将取消函数作为参数传递似乎是唯一的选择(请参见下面的代码片段)。例如,下面代码片段中的代码 Done 通道仅在执行 function2 时才被激活。
package main
import (
"context"
"fmt"
"time"
)
func function1(ctx context.Context) {
_, cancelFunction := context.WithCancel(ctx)
fmt.Println("cancel called from function1")
cancelFunction()
}
func function2(ctx context.Context, cancelFunction context.CancelFunc) {
fmt.Println("cancel called from function2")
cancelFunction()
}
func main() {
//Make a background context
ctx := context.Background()
//Derive a context with cancel
ctxWithCancel, cancelFunction := context.WithCancel(ctx)
go function1(ctxWithCancel)
time.Sleep(5 * time.Second)
go function2(ctxWithCancel, cancelFunction)
time.Sleep(5 * time.Second)
// Done signal is only received when function2 is called
<-ctxWithCancel.Done()
fmt.Println("Done")
}
那么,传递这个取消函数真的是个问题吗?是否有与使用 context 包及其取消功能相关的最佳实践?