go的context包详解,context中文翻译过来叫“上下文”,本篇文章讲一下它具体的作用是什么。你在什么情况下可以用到它。
引言
http server 常为每个请求创建一个 goroutine 以并发地处理请求,同时这个 goroutine 又会创建更多的 gotoutine 来访问数据库和缓存或RPC服务,当请求结束或被终止,能释放所有 gotoutine的资源。因此就需要一种机制,在goroutine之间传递信号消息。
简介
context 中文翻译过来叫”上下文“,常被用来 goroutine 之间传递信息和信号的。信息和信号包括截至时间(deadline),取消信号(cancellation signals) 以及跨边界需要往下传递的键值对信息。
特性
- context的设计是可通过已有Context进行树型派生,已管理一组过程的生命周期。单Context是不可变的,但可以通过WithValue、WithCancel、WithTimeout方法进行派生并附加一些属性(键值、可取消、时限),以构建一组树型组织的context。
- 当根 Context 结束时,所有由其派生出的 Context 也会被一并取消。也就是说,父 Context 的生命周期涵盖所有子 Context 的生命周期。
使用
创建根Context
context.Background()
创建一个空的Context(not nil), 常用作初始化创建根Context。
派生携带键值信息Context
context.WithValue(parentContext, key, value)
在父节点Context的基础上创建一个新的携带键值信息的的子节点Context。
派生可取消Context
context.WithCancel(parentContext)
在父节点Context的基础上创建一个新的可取消的子节点Context,返回新创建的子节点Context和取消方法cancelFunc。
派生有时间限制Context
context.WithTimeout(parentContext,timeout)
在父节点Context的基础上创建新的有时间限制的子节点Context,返回新创建子节点Context和取消方法cancelFunc。超过时间限制后,该Conext会发送信号到Done通道,所有子节点检测到信号立即退出。
派生有截至时间Context
context.WithDeadline(parentContext, time)
在父节点Context的基础上创建新的有截至时间的子节点Context,返回新创建子节点Context和取消方法cancelFunc。context.Timeout(parentContext,timeout)
等价于context.Deadline(parentContext,time.Now().Add(timeout))
。
注意
- Background 创建的根节点没有时限,也不能取消。
- WithCancel、WithTimeout、WithDeadline方法是从父context派生出新的context,新的context受限与父context的生命周期。新context应注意在对应过程结束后及时cancel,以防止goroutine泄露。
- 不能使用nil Context,尽管语法上允许。不知道使用什么值合适时,可以使用
context.TODO()
。