【发布时间】:2021-12-30 16:31:42
【问题描述】:
我一直在阅读一些关于使用 golang 的 context 包的文章。我最近在博客中看到了以下文章:http://p.agnihotry.com/post/understanding_the_context_package_in_golang/
文章对 go 中的上下文取消函数进行了如下说明:
"如果你愿意,你可以传递取消函数,但是, 强烈不推荐。这可能导致取消的调用者不 意识到取消上下文可能对下游产生的影响。 可能有由此衍生的其他上下文可能导致 程序以意想不到的方式运行。简而言之,绝不通过 围绕取消功能。”
但是,如果我希望激活父 context.Done() 通道,将取消函数作为参数传递似乎是唯一的选择(参见下面的代码 sn-p)。比如下面代码sn-p中的代码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 包及其取消功能相关的最佳实践?
【问题讨论】:
标签: go go-context