1

context是一个在 golang 中时常用到的程序包,特别常见的一个应用场景是由一个请求衍生出的各个goroutine之间需要满足一定的约束关系,以实现一些诸如有效期,中止routine树,传递请求全局变量之类的功能。

比如:
上层需要指定超时的情况: ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)

上层需要主动取消的情况:ctx, cancel := context.WithCancel(ctx);需要的地方调用cancel()

context 使用场景:
参数传递(一组groutine ctx共享数据)
超时控制(微服务中请求)
上下文控制(级联取消groutine)

context 为什么是线程安全的?
可以知道添加键值对不是在原context结构体上直接添加,而是以此context作为父节点,重新创建一个新的valueCtx子节点,将键值对添加在子节点上,由此形成一条context链。

Context 类型提供了 Done() 方法,每次 context 接收到取消事件时,该方法都是返回一个 channel,这个 channel 会收到空结构体类型的数据。监听取消事件也很容易,<- ctx.Done()。

对于WithTimeout(或者WithDeadline) 有两种情况

  1. 一种是发生超时了,这个时候cancel 会自动调用,资源被释放。
  2. 另一种没有发生超时,也就是slowOperation结束的时候,这个时候需要咱们主动调用cancel;但是即使没有调用,在过期时间到了的时候还是会调用cancel,释放资源。

cancel 即使不主动调用,也不影响资源的最终释放,但是提前主动调用,可以尽快的释放,避免等待过期时间之间的浪费。
建议还是按照官方的说明使用,养成良好的习惯,在调用WithTimeout之后 defer cancel()

参考:
https://jishuin.proginn.com/p...

https://www.sohamkamani.com/g...

https://mp.weixin.qq.com/s?__...

https://www.jianshu.com/p/c77...


goper
413 声望25 粉丝

go 后端开发


下一篇 »
http.2.0