go context 包


整个 context 包原码就有一个文件即 context.go,我估计 context 的设计就是由 http 引出来的,学习 context 其实也是学习 go 的接口设计范式。

1.1   Context 接口

type Context interface {
	// 取消树和过期时间的实现
	Deadline() (deadline time.Time, ok bool) // 过期时间点
	Done() <-chan struct{} // 过期或者手动取消时关闭通道
	Err() error // 可以判断是过期还是手动取消
	

	// 键值对的实现,valueCtx类型真正实现
	Value(key interface{}) interface{}
}

从这点可以看出,Context 库设计的目的: (1) 退出通知机制 (2) 传递数据

1.2   四个重要的类型

实例化上述四个类型的API函数:

在实例化中,有两条主线: (1) 第一条线是context,上面四个类型是一个衔接一个。后期由 removeChild() 负责找到父节点并从其 children 移除该节点。所以其特点就是向上追溯父节点。 Background(a框) > WithCancel(b框) > WithTimeout(c框,超时3秒) > WithTimeout(d框,超时6秒) > WithValue(e框);需要注意一点的是 d 框不是 timerCtx,因为其超时比父晚,所以会直接生成 cancelCtx。 context 链 (2) 第二条线是 children,只有 cancelCtx 和 timerCtx 能串成链,如果上级不是这两个类型,再继续向上上级找,直到找到才挂靠。由 propagateCancel() 和 parentCancelCtx() 这两个函数负责该逻辑。所以其特点是就向下一级一级取消子节点。

1.3   重要的内部函数