go context

为什么需要context

  • context可以主要用来在goroutine中传递上下文信息
    • 包括取消信号,超时时间,截止时间,k-v等
  • 利用context关闭树状goroutine链
    • 当go服务处理一个请求时,可以需要开多个goroutine,形成goroutine链
      • 例如一个区数据库拿数据,一个调用下游接口等等
    • 如果这个请求被取消了(例如刷新了浏览器或者超时了),那么下游goroutine都应该及时退出
      • 因为他们的“工作成果”不再被需要了
      • 如果不及时退出,可能会造成协程数量激增,内存耗尽
  • 利用context传递数据
    • 坏处
      • 传递的是空接口,需要断言,开销较大
      • 值在传递过程中可能被后续服务覆盖,不易发现,也不易委会
    • 常见传递数据类型
      • 日志信息
      • 调试信息

context的使用

  • context应该作为函数的第一个参数
    • 不知道传递什么context时不要传nil,应该传context.TODO()

func f() {
    // 取消
    ctx1, cancel := context.WithCancel(context.Background())
    defer cancel()
    
    // 超时
    ctx2, _ := context.WithTimeout(ctx1, 5*time.Second)
    // 截止
    dur := time.Now().Add(5 * time.Second)
    ctx3, cancel := context.WithDeadline(ctx2, dur)
    // 传值
    ctx4 := context.WithValue(ctx3, "key", "val")

    go func() {
        for {
            select {
            case <-ctx1.Done():
            	return
            case <-time.Tick(time.Second):
                fmt.Println(ctx4.Value("key"))
            }
        }
    }()
    
    time.Sleep(10 * time.Second)
}

context实现原理

发布了161 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/winter_wu_1998/article/details/102982194