您现在的位置是:热点 >>正文
细数 Context 使用场景
热点87084524人已围观
简介...
你好,我是四哥。
前一篇文章从源码的角度详细介绍了 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").( Cstring))
}
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 {te;
case 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) // 模拟业务逻辑处理
respC 使 }()
// 取消机制
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.WithCancel(co用场ntext.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(), tim Ce.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 个数,那么就会发生 goronoutine 泄漏:
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 int)
go func(te) {
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() // 避免其他地方忘记 cancel,且重复调用不xt影响
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/
Tags:
相关文章
标签: 吐司 腾讯 vibe coding 应用生成
热点云梦级5月15日云梦级消息,Tech星球独家获悉,腾讯内部孵化的探索型vibe coding产品“吐司”即将上线。这款定位为“应用生成及灵感共创平台”的产品,核心亮点的是无需代码基础,用户仅凭自然语言...
【热点】
阅读更多菜花变紫是怎么回事
热点花菜发紫是怎么回事?你好,没事的自然现象因为咱们吃得白花菜是属于没有完全开放的花蕾之类的东东开花后它的茎部就是略紫色+白色的所以时间长了或者晚些收获就会发紫了。。花菜变紫是怎么回事?平时浇水不当所致,...
【热点】
阅读更多快手可灵 2.5Turbo 模型强势登顶全球视频生成榜单!
热点在全球视频生成技术的激烈竞争中,快手的可灵 2.5Turbo 模型近日以卓越表现引起了广泛关注。根据全球知名 AI 基准测试机构 Artificial Analysis 的最新发布,该模型在图生视频和...
【热点】
阅读更多
热门文章
最新文章
友情链接
- 标签: 康师傅
- https://www.ushmm.org/search/results.php?q=谷歌收录霸屏【tg:seogoogle987】,TTq
- https://www.nyif.com/catalogsearch/result/?q=谷歌收录霸屏【tg:seogoogle987】,3XR
- https://www.mintos.org/?s=谷歌收录霸屏【tg:seogoogle987】,Blt
- https://www.teamlab.art/fr/?submit=谷歌收录霸屏【tg:seogoogle987】,mYI
- https://www.urmc.rochester.edu/news/search?q=谷歌收录霸屏【tg:seogoogle987】,rVV
- https://www.lauben.com/en/?action=SEARCH&s=谷歌收录霸屏【tg:seogoogle987】,Vcn
- https://www.southmeadows.co.uk/2019/07/?s=谷歌收录霸屏【tg:seogoogle987】,4zR
- https://www.whatsonstage.com/search?cat=64&term=谷歌收录霸屏【tg:seogoogle987】,SIA
- https://www.tmtpost.com/search?q=谷歌收录霸屏【tg:seogoogle987】,cDE
- https://www.kawainter.com/catalogsearch/result/?q=谷歌收录霸屏【tg:seogoogle987】,qeg
- https://www.sensorshop24.de/catalogsearch/result/index/?type=132&q=谷歌收录霸屏【tg:seogoogle987】,wDQ
- https://www.nyif.com/catalogsearch/result/index/?f=sarbanesoxleyU&index=me_cms_pe&lit=20&mode=list&p=1&q=谷歌收录霸屏【tg:seogoogle987】,RCU
- https://www.kores.com/?s=谷歌收录霸屏【tg:seogoogle987】,gMO
- https://www.yr.no/en/search?q=谷歌收录霸屏【tg:seogoogle987】,xDj
- https://www.wellbees.com/catalogsearch/result/?action=CHECK&q=谷歌收录霸屏【tg:seogoogle987】,zYb
- https://www.scivee.tv/?s=谷歌收录霸屏【tg:seogoogle987】,Z3w
- https://www.selfsufficientish.com/main/?s=谷歌收录霸屏【tg:seogoogle987】,lr0
- https://www.libros.unam.mx/catalogsearch/result/?cat=37&dir=asc&format=20&lit=20&manufacturer=3230&mode=list&order=year_edition&q=谷歌收录霸屏【tg:seogoogle987】,VXQ
- https://www.samen-maier.at/search/谷歌收录霸屏【tg:seogoogle987】,Dh2
- https://www.wuv.edu/?s=谷歌收录霸屏【tg:seogoogle987】,RwL
- https://www.takachi-enclosure.com/search?eqYB=gnI31Ou&text=谷歌收录霸屏【tg:seogoogle987】,HxV
- https://www.kaskus.co.id/search?q=谷歌收录霸屏【tg:seogoogle987】,WOy
- https://www.tombow.com/search/谷歌收录霸屏【tg:seogoogle987】,TDF
- https://www.vocabulary.com/dictionary/谷歌收录霸屏【tg:seogoogle987】,t1S
- https://m.shoppinghow.kakao.com/m/search/q/谷歌收录霸屏【tg:seogoogle987】HwU
- https://www.supersauna.de/catalogsearch/result/?q=谷歌收录霸屏【tg:seogoogle987】,zWw
- https://store.line.me/search/sticker/ja?q=谷歌收录霸屏【tg:seogoogle987】h0a
- https://www.kubb-tool.bfs.admin.ch/en/search?action=CHECK&q=谷歌收录霸屏【tg:seogoogle987】,asS
- https://www.xvideos.com/tags/谷歌收录霸屏【tg:seogoogle987】,Jdn
- https://www.partilerdunyasi.com/index.php?route=product/search&tag=谷歌收录霸屏【tg:seogoogle987】,HYu
- https://hsmoa.com/search?query=谷歌收录霸屏【tg:seogoogle987】Cf7
- https://www.symatoys.com/search.html?ID=UyMD6aO58bPrJvQAB1I0N69KzJBZeNPC&keyword=谷歌收录霸屏【tg:seogoogle987】,lbw
- https://www.remit.co.jp/pt/?action=CHECK&s=谷歌收录霸屏【tg:seogoogle987】,uRF
- https://www.yidian51.com/taobao/谷歌收录霸屏【tg:seogoogle987】,X9r
- https://www.lneg.pt/en/?s=谷歌收录霸屏【tg:seogoogle987】,hKd
- https://www.kaliastyle.com/catalogsearch/result/?q=GOOGLE谷歌收录霸屏【tg:seogoogle987】,IRL
- https://www.wmfe.org/?s=谷歌收录霸屏【tg:seogoogle987】,xby
- https://www.pixiv.net/tags/谷歌收录霸屏【tg:seogoogle987】,j63
- https://www.tcv.org.uk/search/谷歌收录霸屏【tg:seogoogle987】,OEj
- https://www.pickett.co.uk/collections/vendors?q=谷歌收录霸屏【tg:seogoogle987】,cPW
- https://www.sportbiketracktime.com/index.php?route=product/search&tag=谷歌收录霸屏【tg:seogoogle987】,15g
- https://www.thedp.com/page/search?q=谷歌收录霸屏【tg:seogoogle987】,RIZ
- https://www.pearlstonecenter.org/search/谷歌收录霸屏【tg:seogoogle987】,qPg
- https://www.universal-music.co.jp/?ID=1sIcckCTeBS8FjzCshAW9w53s8gr691o&s=谷歌收录霸屏【tg:seogoogle987】,MDG
- https://www.sbaad.no/?s=谷歌收录霸屏【tg:seogoogle987】,Qcj
- https://www.target.com/s?searchTerm=谷歌收录霸屏【tg:seogoogle987】,XEi
- https://www.uctronics.com/catalogsearch/result/?q=谷歌收录霸屏【tg:seogoogle987】,y12
- https://search.danawa.com/dsearch.php?query=谷歌收录霸屏【tg:seogoogle987】yEW
- https://www.nbm.org/?action=QUERY&s=谷歌收录霸屏【tg:seogoogle987】,rzQ
- https://www.zalora.sg/catalog/?cat=112&q=谷歌收录霸屏【tg:seogoogle987】,G3k