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) 有两种情况
- 一种是发生超时了,这个时候cancel 会自动调用,资源被释放。
- 另一种没有发生超时,也就是slowOperation结束的时候,这个时候需要咱们主动调用cancel;但是即使没有调用,在过期时间到了的时候还是会调用cancel,释放资源。
cancel 即使不主动调用,也不影响资源的最终释放,但是提前主动调用,可以尽快的释放,避免等待过期时间之间的浪费。
建议还是按照官方的说明使用,养成良好的习惯,在调用WithTimeout之后 defer cancel()
参考:
https://jishuin.proginn.com/p...
https://www.sohamkamani.com/g...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。