context:用于跨多个 Goroutine 设置截止时间、同步信号、传递上下文请求值(是一个context树),context接口有四个方法Deadline() Done() Err() Value()
- 四种实现:
- emptyCtx:实际是Int,用于创建context树的rootContext,作用就像链表的头结点一样
- cancelCtx:可以取消的 Context,**遍历
children map[canceler]struct{}
**可以递归取消子cancelCtx,父cancelCtx存在其context属性里 - timerCtx:增加了计时器和截止时间的
cancelCtx
,可在特定时间自动取消 - valueCtx:内部包含了两个无限制变量
key, val interface{}
,可无限递归在母Context中查找key但不能在兄弟Context中查找
- withCancel():创建新的cancelCtx并调用propagateCancel()级联
- **
propagateCancel(parent, &c)
**级联context与子context- 父context为done过或已取消,不级联且因为递归取消当前context也需要取消
- 父context未被取消,且父context也是cancelCtx则级联
- 父context未被取消,父context不是cancelCtx无法级联,建立goroutine监听父通信管道取消信号
- cancelCtx.cancel()通过换成一个已经被 close 的 channel让所有
<-c.Done()
停止阻塞取消当前context且遍历所有子context递归取消,最后通过**removeChild()**把自己从父children map[canceler]struct{}移除 - WithDeadline():创建timerCtx
- 父context未取消,截止时间晚于父context不会创建timerCtx,而创建可取消cancel(父取消更早会级联取消)
- 父context未取消,截止时间早于父context创建timerCtx
- timerCtx.cancel():取消timerCtx,掉用cancelcontext的cancel(),并停止计时器
- WithValue():递归向上查找valueCtx存储的key