go context

爲什麼需要context

  • context可以主要用來在goroutine中傳遞上下文信息
    • 包括取消信號,超時時間,截止時間,k-v等
  • 利用context關閉樹狀goroutine鏈
    • 當go服務處理一個請求時,可以需要開多個goroutine,形成goroutine鏈
      • 例如一個區數據庫拿數據,一個調用下游接口等等
    • 如果這個請求被取消了(例如刷新了瀏覽器或者超時了),那麼下游goroutine都應該及時退出
      • 因爲他們的“工作成果”不再被需要了
      • 如果不及時退出,可能會造成協程數量激增,內存耗盡
  • 利用context傳遞數據
    • 壞處
      • 傳遞的是空接口,需要斷言,開銷較大
      • 值在傳遞過程中可能被後續服務覆蓋,不易發現,也不易委會
    • 常見傳遞數據類型
      • 日誌信息
      • 調試信息

context的使用

  • context應該作爲函數的第一個參數
    • 不知道傳遞什麼context時不要傳nil,應該傳context.TODO()

func f() {
    // 取消
    ctx1, cancel := context.WithCancel(context.Background())
    defer cancel()
    
    // 超時
    ctx2, _ := context.WithTimeout(ctx1, 5*time.Second)
    // 截止
    dur := time.Now().Add(5 * time.Second)
    ctx3, cancel := context.WithDeadline(ctx2, dur)
    // 傳值
    ctx4 := context.WithValue(ctx3, "key", "val")

    go func() {
        for {
            select {
            case <-ctx1.Done():
            	return
            case <-time.Tick(time.Second):
                fmt.Println(ctx4.Value("key"))
            }
        }
    }()
    
    time.Sleep(10 * time.Second)
}

context實現原理

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