context原理与关键代码分析
type Context interface
Context
是 Go 语言标准库中的一个接口,定义了与请求的生命周期相关的操作和值的传递。
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{
}
Err() error
Value(key interface{
}) interface{
}
}
Context
接口定义了以下四个方法:
Deadline() (deadline time.Time, ok bool)
:返回上下文的截止时间和一个布尔值,指示是否设置了截止时间。如果设置了截止时间,ok
的值为true
,否则为false
,可多次获取,返回相同的结果。截止时间用于限制操作的执行时间。Done() <-chan struct{}
:返回一个只读通道(<-chan
),当上下文被取消、超时或其他原因导致上下文结束时,该通道将被原子性写入var closedchan = make(chan struct{})
。可以通过监听该通道来接收上下文结束的信号。Err() error
:返回上下文结束的原因。如果上下文正常结束,返回nil
。如果上下文被取消,返回context.Canceled
错误;如果上下文超时,返回context.DeadlineExceeded
错误。Value(key interface{}) interface{}
:返回与给定键关联的值,如果没有value关联到对应的key,会返回nil,重复调用会返回相同的值。上下文可以传递一些键值对的数据,供请求中的不同组件共享和访问。
通过这些方法,我们可以获取上下文的截止时间、接收上下文结束的信号、获取上下文的结束原因以及获取上下文中传递的值。
Context
接口的实现类型有多种,包括 context.Background()
、context.TODO()
、context.WithCancel()
、context.WithDeadline()
、context.WithTimeout()
等。通过这些函数创建的上下文对象可以用于控制并传递请求的上下文信息,实现请求的超时控制、取消操作、值传递等功能。
四种context struct
emptyCtx
结构体:
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return time.Time{
}, false
}
func (*emptyCtx) Done() <-chan struct{
} {
return closedchan
}
func (*emptyCtx) Err() error {
return nil
}
func (*emptyCtx) Value(key interface{
}) interface{
} {
return nil
}
emptyCtx
是一个空的结构体,没有任何成员变量。Deadline()
方法返回一个零值的时间和false
,表示没有设置截止时间。Done()
方法返回一个已关闭的通道,用于表示上下文的结束。Err()
方法返回nil
,表示上下文没有发生任何错误。Value()
方法返回nil
,表示上下文中没有传递任何值。- 该结构体是
background
、todo
的原型,直接new(emptyCtx)
。
cancelCtx
结构体:
type cancelCtx struct {
Context
mu sync.Mutex
done chan struct{
} // 用于通知上下文的结束
children map[canceler]struct{
} // 子上下文集合
err error // 上下文的结束原因
cause error // 上下文的取消原因
}
cancelCtx
是实现了取消功能的上下文结构体。Context
字段保存了parent context
。mu
是用于保护结构体成员的互斥锁。done
是一个通道,用于通知上下文的结束。当上下文被取消时,该通道会被关闭。children
是一个canceler
类型的映射,用于保存该parent context
的children context
。err
是上下文的结束原因,用于标识上下文的取消或其他错误,如果是使用cancel()
函数取消的,err为Canceled
,new 出来的错误类型。cause
是上下文的取消原因,用于标识导致上下文被取消的具体原因。- 该结构体为
context.WithCancel()
生成的context的原型。
timerCtx
结构体:
type timerCtx struct {
cancelCtx
timer *time.Timer // 用于定时的计时器
deadline time.Time // 截止时间
}
timerCtx
是在cancelCtx
的基础上实现了定时功能的上下文结构体。cancelCtx
字段保存了parent context withCancel
成员变量。timer
是用于定时的time.Timer
结构体,用于在指定时间后触发上下文的结束。deadline
是截止时间,用于限制操作的执行时间。- 该结构体是
context.WithDeadline()
、context.WithTimeout()
的原型。
valueCtx
结构体:
type valueCtx struct {
Context
key, val interface{
} // 键值对
}
valueCtx
是实现了值传递功能的上下文结构体。Context
字段保存了paremt context
。key
和val
是键值对,用于在上下文中传递值。- 该struct是
context.WithValue
函数创建的上下文的原型,不具备取消功能。
这些上下文结构体之间的关系如下:
emptyCtx
可以作为上下文树的根节点,作为其他上下文类型的基础。cancelCtx
是在emptyCtx
的基础上实现了取消功能,可以作为其他上下文类型的基础,包括timerCtx
。timerCtx
是在cancelCtx
的基础上扩展实现了定时功能。valueCtx
可以作为叶子节点的上下文,或者作为其他上下文类型的父上下文,用于传递值。
主要函数分析
- WithCancel
func