Golang學習筆記-Context

有時候一個功能可能涉及多個goroutine的調用,當該功能中途需要取消時,需要通知其它goroutine,這個時候Context就可以派上用場了,Context主要用來處理退出通知以及上下文數據傳遞問題。

Context之間被設計爲父子關係,要創建Context,首先要創建根節點,通常是context.Background(),該Context不能被取消,沒有值,也沒有過期時間。

有了根節點後,接下來就是創建子節點,子節點還可以繼續創建子節點,有四種方式創建子節點:WithCancel/WithDeadline/WithTimeout/WithValue,前三種方法都會返回Context和CancelFunc,父節點通過調用CancelFunc通知子節點取消,子節點通過Context提供的Done方法檢測是否被取消。WithValue將一對key-value關聯到Context,通過Context提供的Value方法獲取指定key對應的value。

WithDeadline/WithTimeout創建的Context在超時後會自動調用CancelFunc,如果調用沒有超時,需要主動調用CancelFunc以避免不必要的資源浪費,所以通常在在調用WithDeadline/WithTimeout之後會使用defer cancel()確保資源儘快釋放。

package main

import (
    "context"
    "fmt"
    "time"
)


func say(ctx context.Context){
    for{
        select {
        case <-ctx.Done():
            return
        default:
            fmt.Println(ctx.Value("test"))
            time.Sleep(time.Second)
        }
    }

}


func main(){
    //5秒後調用cancelFunc取消say
    ctx,cancelFunc:=context.WithCancel(context.Background())
    ctx=context.WithValue(ctx,"test","hello")
    go say(ctx)
    time.Sleep(time.Second*5)
    cancelFunc()



    //2秒後調用cancelFunc取消say
    ctx,_=context.WithTimeout(context.Background(),time.Second*2)
    ctx=context.WithValue(ctx,"test","world")
    go say(ctx)

    time.Sleep(time.Second*5)
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章