乐趣区

golang-context-小记

// propagateCancel arranges for child to be canceled when parent is.
func propagateCancel(parent Context, child canceler) {if parent.Done() == nil {return // parent is never canceled}
    if p, ok := parentCancelCtx(parent); ok {p.mu.Lock()
        if p.err != nil {
            // parent has already been canceled
            child.cancel(false, p.err)
        } else {
            if p.children == nil {p.children = make(map[canceler]struct{})
            }
            p.children[child] = struct{}{}
        }
        p.mu.Unlock()} else {
   // 开始不太理解这里:// 1. 在 cancel 函数里会主动的将所有 child cancel 掉,为何还要这个协程来进行 cancel。// 2. 为何还要监听 child.Done().
   // 解答:// 1. 注意下这里的 if else 结构,能走到这里的条件是,向上查找父 context 的过程中,没有发现 cancleCtx 的 context。而只有 cancelCtx 有 cancel 函数。没有 cancel 函数的话,只能这样用协程的方式监听 Done() 了。// 2. 监听 child.Done() 是因为 child 执行结束或被 cancel 的时候,这个协程就可以退出了,没必要等 parent 结束。go func() {
            select {case <-parent.Done():
                child.cancel(false, parent.Err())
            case <-child.Done():}
        }()}
}
退出移动版