Go語言的context package

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Go語言的context package可以把一組用來處理同一請求的函數和goroutine通過context.Context這個類型的變數關聯起來,並提供了取消(cancelation)和逾時(timeout)機制。個人覺得Sameer Ajmani的這篇文檔:Cancelation, Context, and Plumbing寫得很清晰,更容易讓人理解context package

更新1:下列關於Context的定義選自Go Concurrency Patterns: Context:

// A Context carries a deadline, cancelation signal, and request-scoped values// across API boundaries. Its methods are safe for simultaneous use by multiple// goroutines.type Context interface {    // Done returns a channel that is closed when this Context is canceled    // or times out.    Done() <-chan struct{}    // Err indicates why this context was canceled, after the Done channel    // is closed.    Err() error    // Deadline returns the time when this Context will be canceled, if any.    Deadline() (deadline time.Time, ok bool)    // Value returns the value associated with key or nil if none.    Value(key interface{}) interface{}}

四個函數定義如下:
a)Done函數返回一個唯讀channel,因此對其操作只有close。而這個channel只在Contextcanceltimeout的情況下才會被close
b)Err則是在Done channelclose後,用來獲得close的原因,並返回一個non-nil的值:context canceledcontext deadline exceeded
c)Deadline返回Contextcancel的時間。如果okfalse,則表明沒有設定deadline
d)Value返回同key綁定的值,如果沒有相應的值,則返回nil

更新2:簡單地分析一下源碼:

// An emptyCtx is never canceled, has no values, and has no deadline.  It is not// struct{}, since vars of this type must have distinct addresses.type emptyCtx intfunc (*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 (e *emptyCtx) String() string {    switch e {    case background:        return "context.Background"    case todo:        return "context.TODO"    }    return "unknown empty Context"}var (    background = new(emptyCtx)    todo   = new(emptyCtx))

context.Background()context.TODO()所返回的其實都是一個指向emptyCtx類型變數的指標。

再看一下WithCancel()函數實現:

// 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.func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {    c := newCancelCtx(parent)    propagateCancel(parent, c)    return c, func() { c.cancel(true, Canceled) }}// newCancelCtx returns an initialized cancelCtx.func newCancelCtx(parent Context) *cancelCtx {    return &cancelCtx{        Context: parent,        done:    make(chan struct{}),    }}

cancelCtx定義如下:

// A cancelCtx can be canceled.  When canceled, it also cancels any children// that implement canceler.type cancelCtx struct {    Context    done chan struct{} // closed by the first cancel call.    mu       sync.Mutex    children map[canceler]bool // set to nil by the first cancel call    err      error             // set to non-nil by the first cancel call}

每次調用WithCancel函數,新產生的Context會包含“父Context”以及一個新的done channel

propagateCancel()函數實現如下:

// 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]bool)            }            p.children[child] = true        }        p.mu.Unlock()    } else {        go func() {            select {            case <-parent.Done():                child.cancel(false, parent.Err())            case <-child.Done():            }        }()    }}

這個函數就是把新產生的Context加到父Contextchildren成員中,這樣可以形成“級聯”的cancel操作。

其它參考資料:
package context;
Concurrent patterns in Golang: Context;
Context and Cancellation of goroutines。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.