细数 Context 使用场景

  发布时间:2026-11-16   作者:玩站小弟   我要评论
谷歌霸屏外推技术【tg:seogoogle987】。

你好,我是四哥。

前一篇文章从源码的角度详细介绍了 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").(str Cing))
}

func main() {
ctx := context.Background()
func1(ctx)
}

我们在 func1() 通过函数 WithValue() 设置了一个键值对 k1-v1,在 func2() 可以获取到 func1() 设置的键值对,如果调用 func3() 时把这个 ctx 继续传入的话,在 func3() 中依然还是可以获取到 k1-v1。

但是在 func1() 中获取不到 func2() 设置的键值对 k2-v2,因为 conontext 只能自上而下携带值,这点需要注意。

2.取消耗时操作,及时释放资源。

使用 channel + select 的机制:

func func1() error {
respC := make(chan int) // 起消息通知作用
// 处理逻辑
go func() {
time.Sleep(time.Second * 3) // 模拟处理业务逻辑
respC close(respC)
}()

// 判断是否超时
select {
casete 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 ", errxt)
}

上面的方式平时也会用到,通过 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(), t Cime.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() // 避免其他地方忘记 canxtcel,且重复调用不影响

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/

  • Tag:

相关文章

  • 自然语言处理(NLP)的历史及其发展方向

    自然语言处理的历史是一个充满曲折的故事。它从徒劳的研究开始,经过多年卓有成效的工作,最后结束于一个我们仍在试图找出该领域极限的时代。今天,让我们来一起探索这一AI科学分支的发展。 自然语言处理 (NL
    2026-11-16
  • Facebook效仿Clubhouse发力社交音频:近期或推多款新产品

    新浪科技讯 北京时间4月19日上午消息,据报道,知情人士透露,Facebook计划发布一系列新的“社交音频”产品,包括一款与Clubhouse语音社交品台相似的产品,以及一款与Spotify合作开发的
    2026-11-16
  • “马其诺防线”失效,如何做好容器云安全?

    第一次世界大战之后,为了防止德军突袭,法国花重金用了十几年时间在德法边境建造了一座延绵390公里的防御工事,内设大炮、壕沟、堡垒,甚至是厨房、医院、工厂,深沟高垒、四通八达——这就是大名鼎鼎的“马奇诺
    2026-11-16
  • 标签: 比亚迪 天神之眼B 激光辅助驾驶 王朝网

    云梦级4月29日云梦级消息,4月28日晚间,比亚迪官方发布公告称,受全球存储硬件成本大幅上涨的影响,比亚迪旗下(王朝网、海洋网、方程豹)部分车型,选装天神之眼B辅助驾驶激光版的价格,将从9900元上调
    2026-11-16
  • 告别扁平化:谷歌全系应用图标大变脸,渐变色设计重塑视觉审美

    谷歌公司正准备为其旗下的应用生态进行一次视觉上的“大手术”。继 2025 年末初步试水后,全新的渐变色图标设计现已确认将覆盖谷歌几乎所有的核心应用程序。 设计风格转向柔和生动 这次更新的核心在于抛弃了
    2026-11-16
  • 尿酸高如何降低

    前言:怎样降低尿酸在生活中,经常会有一些尿酸高的情况的出现,那么对于这种情况,大家有什么了解呢?尿酸高怎么办呢?相信大家很想了解一下,下面就让我们来好好了解一下关于这些方面的情况吧,希望对大家能够有所
    2026-11-16

最新评论