path: Go SDK/src/context/context.go
结构
type Context interface {Deadline() (deadline time.Time, ok bool)Done() <-chan struct{}Err() errorValue(key interface{}) interface{}}
- Deadline():返回context的超时时间,若当前context未设置超时时间,则ok = false;
 - Done():返回一个空结构体类型的channel,当context取消时,会关闭该通道;
 - Err():返回context被取消的原因;
 Value():通过key获取context中绑定的值,协程安全但不推荐使用,协程间通讯应使用channel;
context的实现
emptyCtx
空的context,虽然实现了context接口,但实现的方法内均返回nil或零值。一般在创建其它类型的context时充当根节点使用。
注:context包内的 Background和 TODO函数返回的都是一个emptyCtx实例,不同的是 todo可被静态分析工具用来验证context传递的正确性。结构及相关方法、函数 ```go type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { return }
func (*emptyCtx) Done() <-chan struct{} { return nil }
func (*emptyCtx) Err() error { return nil }
func (*emptyCtx) Value(key interface{}) interface{} { return nil }
func Background() Context { return background }
func TODO() Context { return todo }
var ( background = new(emptyCtx) todo = new(emptyCtx) )
<a name="i9332"></a>### cancelCtx一个可随时取消的context,内部存储了一个空结构体类型的无缓冲channel,利用channel close的广播机制判断上下文是否已取消。<br />可使用WithCancel函数创建cancelCtx的实例。- **结构及相关方法、函数**```gotype cancelCtx struct {// 匿名字段实现的继承关系Context// 互斥锁,保证协程安全mu sync.Mutex// 一个延迟加载的空结构类型的channel,会在Done方法内返回// 1. 执行cancel方法时,若done==nil则赋值为全局变量 closedchan (一个已经关闭的无缓冲的channel),否则关闭done// 2. 执行Done方法时,若done==nil,则创建一个无缓冲的channeldone chan struct{}// 子级上下文,会在第一次执行Done方法时清空children map[canceler]struct{}// 第一次执行Done方法时赋值,记录上下文取消的原因。(err!=nil即表示context已取消)err error}// 创建并返回cancelCtx实例和它的关闭函数func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {}// 重写匿名字段Context的Value方法func (c *cancelCtx) Value(key interface{}) interface{} {}// 重写匿名字段Context的Done方法func (c *cancelCtx) Done() <-chan struct{} {}// 重写匿名字段Context的Err方法func (c *cancelCtx) Err() error {}// 当前上下文的关闭方法,在WithCancel函数返回的闭包内调用func (c *cancelCtx) cancel(removeFromParent bool, err error) {}
- Demo ```go import ( “context” “fmt” “time” )
 
func main() { ctx, cancel := context.WithCancel(context.Background())
go func() {i := 0for {if closed(ctx) {fmt.Println("上下文已关闭")break}fmt.Println(i)i++}}()time.Sleep(time.Nanosecond)cancel()time.Sleep(time.Nanosecond)
}
func closed(ctx context.Context) bool { select { case <-ctx.Done(): return true default: return false } }
<a name="AJtp1"></a>### timeCtx在聚合了cancelCtx的基础上增加了Timeout机制的上下文。可使用WithTimeout和WithDeadline函数创建实例。- **结构及相关方法、函数**```gotype timerCtx struct {// 匿名字段实现的继承关系cancelCtx// 计时器的指针,用来停止计时,防止cancel方法的二次调用timer *time.Timer// 上下文的超时时间deadline time.Time}// 创建并返回cancelCtx实例和它的关闭函数,该上下文会在一段时间后自动取消// 内部实际调用WithDeadline方法func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {}// 创建并返回cancelCtx实例和它的关闭函数,该上下文在到达指定日期时取消func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {}// 重写匿名字段cancelCtx的Deadline方法func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {}// 当前上下的关闭方法,闭包内调用func (c *timerCtx) cancel(removeFromParent bool, err error) {}
- Demo ```go package main
 
import ( “context” “fmt” “time” )
func main() { // 等价于context.WithDeadline(context.Background(), time.Now().Add(time.Nanosecond))) ctx, _ := context.WithTimeout(context.Background(), time.Nanosecond)
go func() {i := 0for {if closed(ctx) {fmt.Println("上下文已关闭")break}fmt.Println(i)i++}}()time.Sleep(time.Second)
}
func closed(ctx context.Context) bool { select { case <-ctx.Done(): return true default: return false } }
<a name="rZn8b"></a>### valueCtx只可存储键值对数据但不能取消的上下文。<br />_注:一个valueCtx只保存一个key和value,使用Value方法取数据时,向上递归调用Context.Value方法。_```gotype valueCtx struct {// 匿名字段实现的继承关系Context// 当前上下文保存的键值对信息key, val interface{}}// 重写匿名字段Context的value方法func (c *valueCtx) Value(key interface{}) interface{} {if c.key == key {return c.val}return c.Context.Value(key)}
