Golang context初探

什么是context

從go1.7開始细移,golang.org/x/net/context包正式作為context包進(jìn)入了標(biāo)準(zhǔn)庫楞黄。那么宛蚓,這個包到底是做什么的呢斜姥?根據(jù)官方的文檔說明:

Package context defines the Context type, which carries deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes.

也就是說洲押,通過context武花,我們可以方便地對同一個請求所產(chǎn)生地goroutine進(jìn)行約束管理,可以設(shè)定超時杈帐、deadline体箕,甚至是取消這個請求相關(guān)的所有g(shù)oroutine。形象地說挑童,假如一個請求過來累铅,需要A去做事情,而A讓B去做一些事情站叼,B讓C去做一些事情娃兽,A、B尽楔、C是三個有關(guān)聯(lián)的goroutine投储,那么問題來了:假如在A、B阔馋、C還在處理事情的時候請求被取消了玛荞,那么該如何優(yōu)雅地同時關(guān)閉goroutine A、B呕寝、C呢勋眯?這個時候就輪到context包上場了。

如何使用context

在開始說明如何使用context之前下梢,先來看看context有什么相關(guān)的方法定義客蹋。
先來看看context的代碼示例:

package main

import (
    "context"
    "log"
    "net/http"
    _ "net/http/pprof"
    "time"
)

func main() {
    go http.ListenAndServe(":8989", nil)
    ctx, cancel := context.WithCancel(context.Background())
    go func() {
        time.Sleep(3 * time.Second)
        cancel()
    }()
    log.Println(A(ctx))
    select {}
}

func C(ctx context.Context) string {
    select {
    case <-ctx.Done():
        return "C Done"
    }
    return ""
}

func B(ctx context.Context) string {
    ctx, _ = context.WithCancel(ctx)
    go log.Println(C(ctx))
    select {
    case <-ctx.Done():
        return "B Done"
    }
    return ""
}

func A(ctx context.Context) string {
    go log.Println(B(ctx))
    select {
    case <-ctx.Done():
        return "A Done"
    }
    return ""
}

運行結(jié)果:

2016/12/25 22:27:00 A Done
2016/12/25 22:27:00 C Done
2016/12/25 22:27:00 B Done

pprof截圖,剛開始的時候:

剛開始.png

A孽江、B讶坯、C結(jié)束后:

結(jié)束后.png

在這里,我們用http的pprof來查看運行時有多少個goroutine正在執(zhí)行竟坛,
go http.ListenAndServe(":8989", nil)
這一句是啟動一個http服務(wù)器闽巩,用來查看程序的一些運行信息。
我們用context.Background()來實例化一個context担汤,然后調(diào)用WithCancel()方法來返回一個context和一個取消的方法涎跨,并在3秒后調(diào)用這個cancel方法關(guān)閉goroutine A、B崭歧、C隅很。從程序的運行結(jié)果看,我們調(diào)用了一次cancel方法,子goroutine的ctx.Done()都收到了關(guān)閉信號叔营。從pprof的截圖也可以看到屋彪,從一開始有5個goroutine,到關(guān)閉后剩下兩個绒尊,也就是A畜挥、B、C三個goroutine都已經(jīng)關(guān)閉了婴谱。
這里的例子是直接調(diào)用了context.WithCancel()蟹但,我們也可以使用context.WithTimeout()context.WithDeadline()來設(shè)置goroutine的超時時間和最終的運行時間。具體的用法可以看一下官方文檔谭羔,這里就不細(xì)說了华糖。另外有一個方法在例子中沒有用到,那就是context.WithValue()瘟裸。這個方法是用來傳遞在這次的請求處理中相關(guān)goroutine的共享變量客叉,這與全局變量是有所區(qū)別的,因為它只在這次的請求范圍內(nèi)有效话告。

context的使用規(guī)范

在最新的1.8 beta版本中兼搏,很多相關(guān)的包都加入了context,比如database包沙郭。那么向族,在使用context的時候有哪些需要注意呢?

  • 不要把context存儲在結(jié)構(gòu)體中棠绘,而是要顯式地進(jìn)行傳遞
  • 把context作為第一個參數(shù),并且一般都把變量命名為ctx
  • 就算是程序允許再扭,也不要傳入一個nil的context氧苍,如果不知道是否要用context的話,用context.TODO()來替代
  • context.WithValue()只用來傳遞請求范圍的值泛范,不要用它來傳遞可選參數(shù)
  • 就算是被多個不同的goroutine使用让虐,context也是安全的

context的初步了解暫時就先說這么多了,以后有空可以研究一下源碼看看context是如何實現(xiàn)的罢荡。

圣誕快樂赡突!

參考文章:
Golang之Context的使用
Golang context

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市区赵,隨后出現(xiàn)的幾起案子惭缰,更是在濱河造成了極大的恐慌,老刑警劉巖笼才,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漱受,死亡現(xiàn)場離奇詭異,居然都是意外死亡骡送,警方通過查閱死者的電腦和手機昂羡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門絮记,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虐先,你說我怎么就攤上這事怨愤。” “怎么了蛹批?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵撰洗,是天一觀的道長。 經(jīng)常有香客問我般眉,道長了赵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任甸赃,我火速辦了婚禮柿汛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埠对。我一直安慰自己络断,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布项玛。 她就那樣靜靜地躺著貌笨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪襟沮。 梳的紋絲不亂的頭發(fā)上锥惋,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音开伏,去河邊找鬼膀跌。 笑死,一個胖子當(dāng)著我的面吹牛固灵,可吹牛的內(nèi)容都是我干的捅伤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼巫玻,長吁一口氣:“原來是場噩夢啊……” “哼丛忆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仍秤,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤熄诡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后徒扶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粮彤,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了导坟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屿良。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惫周,靈堂內(nèi)的尸體忽然破棺而出尘惧,到底是詐尸還是另有隱情,我是刑警寧澤递递,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布喷橙,位于F島的核電站,受9級特大地震影響登舞,放射性物質(zhì)發(fā)生泄漏贰逾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一菠秒、第九天 我趴在偏房一處隱蔽的房頂上張望疙剑。 院中可真熱鬧,春花似錦践叠、人聲如沸言缤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽管挟。三九已至,卻和暖如春弄捕,著一層夾襖步出監(jiān)牢的瞬間僻孝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工守谓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皮璧,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓分飞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睹限。 傳聞我的和親對象是個殘疾皇子譬猫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)羡疗,斷路器染服,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 控制并發(fā)有三種種經(jīng)典的方式,一種是通過channel通知實現(xiàn)并發(fā)控制 一種是WaitGroup叨恨,另外一種就是Con...
    wiseAaron閱讀 10,646評論 4 34
  • 注1:此文有版權(quán)柳刮。如借用或引用,請聯(lián)系博主。 注2:文中照片系金蓮花禪文化主題酒店提供秉颗。 一 五臺山流傳著這樣一個...
    大可can713閱讀 1,598評論 3 8
  • 我負(fù)笈來榕痢毒,問學(xué)于福建師大已兩年有余了。榕城風(fēng)物頗有特色蚕甥,隨處可見的榕樹哪替,偏甜的飲食,還有各式各樣的海鮮菇怀,都給我留...
    文可清心也閱讀 728評論 0 1
  • 本系列文章是對 http://metalkit.org 上面MetalKit內(nèi)容的全面翻譯和學(xué)習(xí). MetalKi...
    蘋果API搬運工閱讀 1,780評論 0 6