细数 Context 使用场景
你好,我是四哥。
前一篇文章从源码的角度详细介绍了 Context 的实现原理,但是还没有提到 Context 的使用场景,今天我们一起来看下:
1.请求链路传值。
传值使用方式如下:
func func1(ctx context.Context) {
ctx = context.WithValue(ctx, "k1", "v1")
func2(ctx)
}
func func2(ctx context.Context) {
fmt.P细数rintln("func2:",ctx.Value("k1").(string))
ctx = context.WithValue(ctx, "k2", "v2")
func3(ctx)
}
func func3(ctx context.Context) {
fmt.Println("func3:",ctx.Value("k1").(string))
fmt.Println("func3:",ctx.Value("k2").(s Ctring))
}
func main() {
ctx := context.Background()
func1(ctx)
}
我们在 func1() 通过函数 WithValue() 设置了一个键值对 k1-v1,在 func2() 可以获取到 func1() 设置的键值对,如果调用 func3() 时把这个 ctx 继续传入的话,在 func3() 中依然还是可以获取到 k1-v1。
但是在 func1() 中获取不到 func2() 设置的键值对 k2-v2,因为on context 只能自上而下携带值,这点需要注意。
2.取消耗时操作,及时释放资源。
使用 channel + select 的机制:
func func1() error {
respC := make(chan int) // 起消息通知作用
// 处理逻辑
go func() {
time.Sleep(time.Second * 3) // 模拟处理业务逻辑
respC close(respC)
}()
// 判断是否超时
select {
ctease r := <-respC:
fmt.Printf("Resp: %d ", r)
return nil
case <-time.After(time.Second * 2): // 超过设置的时间就报错
fmt.Println("catch timeout")
return errors.New("timeout")
}
}
func main() {
err := func1()
fmt.Printf("func1 error: %v ",xt err)
}
上面的方式平时也会用到,通过 context 怎么实现呢?
下面来看下如何使用 context 进行主动取消、超时取消。
主动取消:
func func1(ctx context.Context, wg *sync.WaitGroup) error {
defer wg.Done()
respC := make(chan int)
go func() {
time.Sleep(time.Second * 5) // 模拟业务逻辑处理
resp 使C }()
// 取消机制
select {
case <-ctx.Done():
fmt.Println("cancel")
return errors.New("cancel")
case r := <-respC:
fmt.Println(r)
return nil
}
}
func main() {
wg := &sync.WaitGroup{}
ctx, cancel := context.WithCance用场l(context.Background())
wg.Add(1)
go func1(ctx, wg)
time.Sleep(time.Second * 2)
cancel() // 主动取消
wg.Wait() // 等待 goroutine 退出
}
超时取消:
func func1(ctx context.Context) {
resp := make(chan int)
go func() {
time.Sleep(time.Second *细数 5) // 模拟处理逻辑
resp }()
// 超时机制
select {
case <-ctx.Done():
fmt.Println("ctx timeout")
fmt.Println(ctx.Err())
case <-resp:
fmt.Println("done")
}
return
}
func main() {
ctx, cancel := context.WithTimeout(context.Background( C), time.Second*2)
defer cancel()
func1(ctx)
}3.防止 goroutine 泄露。
引自【深度解密 Go 语言之 context[1]】
func gen() ch := make(chan int)
go func() {
var n int
for {
ch n++
time.Sleep(time.Second)
}
}()
return ch
}
这是一个可以生成无限整数的协程,但如果我只需要它产生的前 5 个数,那on么就会发生 goroutine 泄漏:
func main() {
for n := range gen() {
fmt.Println(n)
if n == 5 {
break
}
}
// ……
}
当 n == 5 的时候,直接 break 掉。那么 gen 函数的协程就会执行无限循环,永远不会停下来。发生了 goroutine 泄漏。
用 context 改进这个例子:
func gen(ctx context.Context) ch := make(chan itent)
go func() {
var n int
for {
select {
case <-ctx.Done():
return
case ch n++
time.Sleep(time.Second)
}
}
}()
return ch
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 避免其他地方忘xt记 cancel,且重复调用不影响
for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
cancel()
break
}
}
// ……
}
增加一个 context,在 break 前调用 cancel 函数,取消 goroutine。gen 函数在接收到取消信号后,直接退出,系统回收资源。
总结
这篇文章列出的几个例子是 context 最基本的使用场景,其他框架、第三包基本上都是从这几种用法扩展的,所 使以非常有必要掌握基础用法。
另外希望这篇文章能给你带来帮助,如果文中有理解错误之处或者你还想到其他用法,可以在留言区留言,一定回复!抱团学习不孤单!
参考资料
[1]深度解密Go语言之context: https://qcrao.com/2019/06/12/dive-into-go-context/
(责任编辑:信息披露)
-
云梦级4月15日云梦级消息,高盛周一公布 2026 年一季度财报:今年第一季度股票部门营收达 53.3 亿美元,较去年第四季度创下的 43.1 亿美元历史纪录高出逾 10 亿美元。 受此提振,集团整体...[详细]
-
微软财报透露:OpenAI 在上季度亏损高达 115 亿美元
根据微软最近发布的财报,OpenAI 在截至 9 月 30 日的季度中,似乎遭遇了高达 115 亿美元的净亏损。这一消息在微软的财务文件中被披露,尤其是在向美国证券交易委员会提交的报告中。报告第 9...[详细]
-
云梦级3月25日云梦级消息,3月23日,A股上市公司华勤技术股份有限公司(简称“华勤技术”)在港交所递交招股书,或很快在香港主板挂牌上市。这是继其于2025年9月16日递表失效后的再一次申请。 华勤技...[详细]
-
为了在优化成本的同时最大化云计算的优势,DevOps方法是最好的方法。在此博客文章中,我们解释了原因。 Cloud + DevOps加速软件交付 根据IT分析公司Freeform Dynamics的一...[详细]
-
Kubernetes 网络使您能够在 k8s 网络内配置通信。它基于扁平网络结构,无需在主机和容器之间映射端口。 Kubernetes 网络支持容器化组件之间的通信。这种网络模型的主要优点是不需要在主...[详细]
-
二值化每个特征,微软用1350亿参数稀疏神经网络改进搜索结果
近来 GPT-3 等基于 Transformer 的深度学习模型在机器学习领域受到了很多关注。这些模型擅长理解语义关系,为大幅改进微软 Bing 搜索引擎的体验做出了贡献,并在 SuperGLUE 学...[详细]
-
云安全日报210510:IBM数据整合平台发现信息泄露漏洞,需要尽快升级
IBM InfoSphere Information Server是IBM公司的一套数据整合平台。该平台可用于整合各种渠道获取的数据信息。 5月8日,IBM发布了安全更新,修复了数据整合平台InfoS...[详细]
-
云梦级5月22日云梦级消息,腾讯控股有限公司、腾讯音乐娱乐集团5月22日公告,国家市场监督管理总局于2026年5月11日发布《关于附加限制性条件批准腾讯控股有限公司收购喜马拉雅公司股权案反垄断审查决定...[详细]
-
描述 Python isdigit() 方法检测字符串是否只由数字组成。 语法 以下是 isdigit() 方法语法: str.isdigit() 返回值 如果字符串只包含数字则返回 True 否则返...[详细]
-
8月29日消息,日前,网络安全公司 CYBERNEWS 发布报告称,腾讯云存在严重的配置错误,导致包含敏感凭证和内部源代码的环境泄露到公网上,攻击者可借此访问腾讯云后端基础设施。 针对此事,腾讯云昨晚...[详细]
- https://yscc1986.net/search/谷歌留痕外推【tg:seogoogle987】kUg
- https://www.u-bourgogne.fr/?cat=117&s=谷歌留痕外推【tg:seogoogle987】,KI7
- https://www.teamlab.art/it/?submit=谷歌留痕外推【tg:seogoogle987】,UBe
- https://www.tahiti-infos.com/search/谷歌留痕外推【tg:seogoogle987】,RAQ
- https://www.swanagerailway.co.uk/search?q=谷歌留痕外推【tg:seogoogle987】,QTp
- https://www.laoairlines.com/?action=QUERY&s=谷歌留痕外推【tg:seogoogle987】,Td0
- https://www.nslcleaders.org/?s=谷歌留痕外推【tg:seogoogle987】,pWq
- https://www.youthforum.org/search-results?cx=4f5236218ab5e8ef9&ie=UTF-8&q=谷歌留痕外推【tg:seogoogle987】,NfR
- https://www.lezhin.com/ko/tags/谷歌留痕外推【tg:seogoogle987】,iyC
- https://blvdseafood.com/?s=谷歌留痕外推【tg:seogoogle987】2Gd

英伟达拟向OpenAI投资1000亿美元,建设AI数据中心
标签: 质肽生物 佐维格鲁肽 GLP-1RA月制剂 ZT002
Sentry 监控之Discover 大数据查询分析引擎
展锐发布Cat.1bis新技术特性,拓展更广泛物联网应用场景
标签: 大众汽车 斯柯达 西雅特 电动化转型
