context源码分析
Golang JDK 1.10.3
Context介绍
假如有多个goroutine来处理一个操作,这个操作有超时时间,当超时时间到了之后,如何通知这个操作的所有goroutine都退出。或者在操作的过程中有一个goroutine遇到异常需要退出,如何通知其他的goroutine也退出该操作? context就可以很好的解决以上问题。
Go服务器的每个请求都有自己的goroutine,而有的请求为了提高性能,会经常启动额外的goroutine处理请求,当该请求被取消或超时,为了防止资源泄露,该请求上的所有goroutines应该退出。那么context来了,它对该请求上的所有goroutines进行约束,然后进行取消信号,超时等操作。
context优点就是简洁的管理goroutines的生命周期。
Context源码分析
1. Context接口
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
Dealine()方法 返回当前上下文的截至时间,即该上下文应该被取消的时间,如果没有设置超时时间,则返回的ok为false
Done()方法 在Context被取消或超时时会close当前监听的channel,close的channel可以作为广播通知,告诉context相关的函数要停止当前工作然后退出。
创建Context时会返回CancelFunc函数,调用CancelFunc函数以及到了超时时间,会关闭Done()方法监听的channel,所以Done()需要放到select中。
父Context取消时,其子Context也会被取消。但是子Context取消时,其父Context不会被取消。
Err()方法 如果Done未关闭,则Err返回nil,如果Done已关闭,则返回非空的error解释原因。
Value方法通过key获取该key在上下文中关联的值,如果该key没有关联的值,则返回nil,多次调用同一个key,返回的结果是一样的。
2. emptyCtx
empty是空的Context,但是实现了Context的接口。emptyCtx没有超时时间,不能被取消,也不能存储任何额外信息,所以emptyCtx常用来作为Context的根节点。
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (*emptyCtx) Done() <-chan struct{} {
ret