Go Context

context上下文的意思, 可以用來(lái)做超時(shí)管理 禀崖,context 可以設(shè)置截止日期箍铭,超時(shí)或調(diào)用取消函數(shù)來(lái)通知所有使用任何派生 context 的函數(shù)來(lái)停止運(yùn)行并返回。
1.創(chuàng)建 context
(1) ctx := context.Background()
返回一個(gè)空 context蜜唾。這只能用于高等級(jí)(在 main 或頂級(jí)請(qǐng)求處理中)用于派生杂曲。
(2) ctx := context.TODO() Context
返回也是空context,與Bg的區(qū)別在于靜態(tài)分析工具可以使用它來(lái)驗(yàn)證 context 是否正確傳遞袁余,這是一個(gè)重要的細(xì)節(jié)擎勘,因?yàn)殪o態(tài)分析工具可以幫助在早期發(fā)現(xiàn)潛在的錯(cuò)誤,并且可以連接到 CI/CD 管道颖榜。

var (
    background = new(emptyCtx)
    todo = new(emptyCtx)
)

2.使用context
(1) context.WithValue(parent Context, key, val interface{}) (ctx Context, cancel CancelFunc)
此函數(shù)接收 context 并返回派生 context棚饵,其中值 val 與 key 關(guān)聯(lián),并通過(guò) context 樹與 context 一起傳遞朱转。這意味著一旦獲得帶有值的 context蟹地,從中派生的任何 context 都會(huì)獲得此值。不建議使用 context 值傳遞關(guān)鍵參數(shù)藤为,而是函數(shù)應(yīng)接收簽名中的那些值,使其顯式化夺刑。

ctx := context.WithValue(context.Background(), key, "test")

(2) context.WithCancel(parent Context) (ctx Context, cancel CancelFunc)
返回派生 context 和取消函數(shù)缅疟。只有創(chuàng)建它的函數(shù)才能調(diào)用取消函數(shù)來(lái)取消此 context分别。如果您愿意,可以傳遞取消函數(shù)存淫,但是耘斩,永遠(yuǎn)不要傳遞取消函數(shù)。

ctx, cancel := context.WithCancel(context.Background())

(3) context.WithDeadline(parent Context, d time.Time) (ctx Context, cancel CancelFunc)
此函數(shù)返回其父項(xiàng)的派生 context桅咆,當(dāng)截止日期超過(guò)或取消函數(shù)被調(diào)用時(shí)括授,該 context 將被取消。例如岩饼,您可以創(chuàng)建一個(gè)將在以后的某個(gè)時(shí)間自動(dòng)取消的 context荚虚,并在子函數(shù)中傳遞它。當(dāng)因?yàn)榻刂谷掌诤谋M而取消該 context 時(shí)籍茧,獲此 context 的所有函數(shù)都會(huì)收到通知去停止運(yùn)行并返回版述。

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(2 * time.Second))

(4) context.WithTimeout(parent Context, timeout time.Duration) (ctx Context, cancel CancelFunc)
此函數(shù)類似于 context.WithDeadline。不同之處在于它將持續(xù)時(shí)間作為參數(shù)輸入而不是時(shí)間對(duì)象寞冯。此函數(shù)返回派生 context渴析,如果調(diào)用取消函數(shù)或超出超時(shí)持續(xù)時(shí)間,則會(huì)取消該派生 context吮龄。

ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)

Demo:
一個(gè)超時(shí)的例子:

package main

import (
  "context"
  "fmt"
  "math/rand"
  "time"
)

/* Context 可以用來(lái)做超時(shí)管理
*
*/

func sleepRandom(fromFunction string, ch chan int){
  defer func(){fmt.Println(fromFunction, "sleepRandom complete")}()

  seed := time.Now().UnixNano()
  r := rand.New(rand.NewSource(seed))
  randomNumber := r.Intn(100)
  sleeptime := randomNumber + 100
  fmt.Println(fromFunction, "starting sleep for", sleeptime, "ms")
  time.Sleep(time.Duration(sleeptime) * time.Millisecond)
  fmt.Println(fromFunction, "Waking up, slept for", sleeptime, "ms")
  if ch != nil{
      ch <- sleeptime
  }
}

func sleepRandomContext(ctx context.Context, ch chan bool){
  defer func(){
      fmt.Println("sleepRandomContext complete")
      ch <- true
  }()
  sleeptimeChan := make(chan int)
  go sleepRandom("sleepRandomContext", sleeptimeChan)

  select{
  case <-ctx.Done():
      fmt.Println("sleepRandomContext: Time to return")
  case sleeptime := <- sleeptimeChan:
      fmt.Println("sleep for ", sleeptime, "ms")
  }
}

func doWorkContext(ctx context.Context){
  ctxWithTimeout, cancelFunction := context.WithTimeout(ctx, time.Duration(100) * time.Millisecond)

  fmt.Println("begin")
  time.Sleep(1 * time.Second)
  defer func(){
      fmt.Println("doWorkContext complete")
      cancelFunction()
  }()

  ch := make(chan bool)
  go sleepRandomContext(ctxWithTimeout, ch)

  select {
  case <- ctx.Done():
      fmt.Println("doWorkContext: Time to return")
  case <- ch:
      fmt.Println("sleepRandomContext returns")
  }

}

func main(){
  ctx := context.Background()

  /*
   * Context 可以用來(lái)做超時(shí)管理俭茧,當(dāng)context關(guān)閉的時(shí)候,函數(shù)也跟著關(guān)閉了
   */

  //cancelFunction 取消函數(shù)
  //可以直接取消當(dāng)前的context,context -> nil
  ctxWithCancel, cancelFunction := context.WithCancel(ctx)

  defer func(){
      fmt.Println("Main Defer: canceling context")
      cancelFunction()
  }()

  go func(){
      time.Sleep(1 * time.Second)
      //sleepRandom("Main", nil)
      cancelFunction()
      fmt.Println("Main Sleep complete. canceling context")
  }()
  doWorkContext(ctxWithCancel)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漓帚,一起剝皮案震驚了整個(gè)濱河市恢恼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胰默,老刑警劉巖场斑,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異牵署,居然都是意外死亡漏隐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門奴迅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)青责,“玉大人,你說(shuō)我怎么就攤上這事取具〔绷ィ” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵暇检,是天一觀的道長(zhǎng)产阱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)块仆,這世上最難降的妖魔是什么构蹬? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任王暗,我火速辦了婚禮,結(jié)果婚禮上庄敛,老公的妹妹穿的比我還像新娘俗壹。我一直安慰自己,他們只是感情好藻烤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布绷雏。 她就那樣靜靜地躺著,像睡著了一般怖亭。 火紅的嫁衣襯著肌膚如雪涎显。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天依许,我揣著相機(jī)與錄音棺禾,去河邊找鬼。 笑死峭跳,一個(gè)胖子當(dāng)著我的面吹牛膘婶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛀醉,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼悬襟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了拯刁?” 一聲冷哼從身側(cè)響起脊岳,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垛玻,沒想到半個(gè)月后割捅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帚桩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年亿驾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片账嚎。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡莫瞬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郭蕉,到底是詐尸還是另有隱情疼邀,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布召锈,位于F島的核電站旁振,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜规求,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一筐付、第九天 我趴在偏房一處隱蔽的房頂上張望卵惦。 院中可真熱鬧阻肿,春花似錦、人聲如沸沮尿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畜疾。三九已至赴邻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啡捶,已是汗流浹背姥敛。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞎暑,地道東北人彤敛。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像了赌,于是被迫代替她去往敵國(guó)和親墨榄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一勿她、Context概述 1.緣起 在開發(fā)web服務(wù)應(yīng)用時(shí)袄秩,我們知道http啟動(dòng)的服務(wù)每接收到一個(gè)請(qǐng)求是便啟動(dòng)一個(gè)g...
    GoFuncChan閱讀 1,272評(píng)論 0 0
  • 引言 context 是 Go 中廣泛使用的程序包,由 Google 官方開發(fā)逢并,在 1.7 版本引入之剧。它用來(lái)簡(jiǎn)化在...
    51reboot閱讀 3,534評(píng)論 0 10
  • 1 什么是Context 最近在公司分析gRPC源碼,proto文件生成的代碼砍聊,接口函數(shù)第一個(gè)參數(shù)統(tǒng)一是ctx c...
    淘小鋪刀仔閱讀 324評(píng)論 0 1
  • 淺析 go context 用法demo WithCancelfunc WithCancel(parent Con...
    超鴿帶你飛閱讀 776評(píng)論 0 1
  • 目錄 Context 基本使用方法 Context 使用場(chǎng)景 valueCtx使用示例結(jié)構(gòu)體WithValue c...
    邁莫coding閱讀 518評(píng)論 0 1