Go Context 基礎入門

簡介

context是Go中廣泛使用的程序包,由Google官方開發在1.7版本引入。它用來簡化在多個go routine傳遞上下文數據、(手動/超時)中止routine樹等操作,比如,官方http包使用context傳遞請求的上下文數據,gRpc使用context來終止某個請求產生的routine樹。由于它使用簡單,現在基本成了編寫go基礎庫的通用規范。

1.使用入門:kv存儲

  • context在整體上看就是一個樹,每個節點只能存儲一個kv對
  • Background() 創建一個根節點
  • WithValue() 父context衍生一個子context,并將key/value對保存到子節點。
  • Value() 從某個節點取出Value,子節點可以取到父節點的kv。

代碼示例:

func main() {
    root := context.Background()
    ctx1 := context.WithValue(root, "key1", "value1")
    ctx2 := context.WithValue(ctx1, "key2", "value2")
    fmt.Println(ctx1.Value("key1"))
    fmt.Println(ctx1.Value("key11"))
    fmt.Println(ctx2.Value("key2"))
}

value1
<nil>
value2

2. 控制并發(goroutine)

當context節點close時,會觸發 Done() 操作,goroutine可以接收次消息通知。

func main() {
    root := context.Background()
    //ctx1, cancel := context.WithDeadline(root, time.Now().Add(6 * time.Second))
    ctx1, cancel := context.WithCancel(root)
    ctx2 := context.WithValue(ctx1, "key2", "value2")
    go watch(ctx2)
    time.Sleep(10 * time.Second)
    fmt.Println("通知監控停止")
    cancel()
    time.Sleep(5 * time.Second)
}

func watch(ctx context.Context) {
    for {
        select {
        case <- ctx.Done():
            fmt.Println(ctx.Value("key2"), "監控退出了。")
            return
        default:
            fmt.Println(ctx.Value("key2"), "go rountine 監控中。。。")
            time.Sleep(2 * time.Second)
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。