Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
mu sync.Mutex // protects following fields 加锁用 done chan struct{} // created lazily, closed by first cancel call 控制channel children map[canceler]struct{} // set to nil by the first cancel call cancel函数调用后,释放子类 err error // set to non-nil by the first cancel call }
timer控制死锁时间结构:
1 2 3 4 5 6 7 8 9 10
// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to // implement Done and Err. It implements cancel by stopping its timer then // delegating to cancelCtx.cancel.
type timerCtx struct { cancelCtx timer *time.Timer // Under cancelCtx.mu.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { if parent == nil { //日常判空 panic("cannot create context from nil parent") } c := newCancelCtx(parent) //cancelCtx new propagateCancel(parent, &c) //循环传播取消函数for ctx return &c, func() { c.cancel(true, Canceled) } }
看似很简单,四行解决,但是更重要的是学会看注释说明和相关的设计思路:
TODO
引用官方的语言:
1 2 3 4 5 6 7 8 9 10 11 12 13
// WithCancel returns a copy of parent with a new Done channel. The returned // context's Done channel is closed when the returned cancel function is called // or when the parent context's Done channel is closed, whichever happens first. // // Canceling this context releases resources associated with it, so code should // call cancel as soon as the operations running in this Context complete.