// 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():            }        }()    }}