站長(zhǎng)資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        Go 語(yǔ)言中的 Context 詳解

        Go 語(yǔ)言中的 Context 詳解

        1. 什么是 Context?

        在 Go 1.7 版本之前,context 還是非編制的,它存在于 golang.org/x/net/context 包中。

        后來(lái),Golang 團(tuán)隊(duì)發(fā)現(xiàn) context 還挺好用的,就把 context 收編了,在 Go 1.7 版本正式納入了標(biāo)準(zhǔn)庫(kù)。

        Context,也叫上下文,它的接口定義如下

        type Context interface {     Deadline() (deadline time.Time, ok bool)     Done() <-chan struct{}     Err() error     Value(key interface{}) interface{} }

        可以看到 Context 接口共有 4 個(gè)方法

        • Deadline:返回的第一個(gè)值是 截止時(shí)間,到了這個(gè)時(shí)間點(diǎn),Context 會(huì)自動(dòng)觸發(fā) Cancel 動(dòng)作。返回的第二個(gè)值是 一個(gè)布爾值,true 表示設(shè)置了截止時(shí)間,false 表示沒(méi)有設(shè)置截止時(shí)間,如果沒(méi)有設(shè)置截止時(shí)間,就要手動(dòng)調(diào)用 cancel 函數(shù)取消 Context。
        • Done:返回一個(gè)只讀的通道(只有在被cancel后才會(huì)返回),類型為 struct{}。當(dāng)這個(gè)通道可讀時(shí),意味著parent context已經(jīng)發(fā)起了取消請(qǐng)求,根據(jù)這個(gè)信號(hào),開(kāi)發(fā)者就可以做一些清理動(dòng)作,退出goroutine。
        • Err:返回 context 被 cancel 的原因。
        • Value:返回被綁定到 Context 的值,是一個(gè)鍵值對(duì),所以要通過(guò)一個(gè)Key才可以獲取對(duì)應(yīng)的值,這個(gè)值一般是線程安全的。

        2. 為何需要 Context?

        當(dāng)一個(gè)協(xié)程(goroutine)開(kāi)啟后,我們是無(wú)法強(qiáng)制關(guān)閉它的。

        常見(jiàn)的關(guān)閉協(xié)程的原因有如下幾種:

        1. goroutine 自己跑完結(jié)束退出
        2. 主進(jìn)程crash退出,goroutine 被迫退出
        3. 通過(guò)通道發(fā)送信號(hào),引導(dǎo)協(xié)程的關(guān)閉。

        第一種,屬于正常關(guān)閉,不在今天討論范圍之內(nèi)。

        第二種,屬于異常關(guān)閉,應(yīng)當(dāng)優(yōu)化代碼。

        第三種,才是開(kāi)發(fā)者可以手動(dòng)控制協(xié)程的方法,代碼示例如下:

        func main() {     stop := make(chan bool)      go func() {         for {             select {             case <-stop:                 fmt.Println("監(jiān)控退出,停止了...")                 return             default:                 fmt.Println("goroutine監(jiān)控中...")                 time.Sleep(2 * time.Second)             }         }     }()      time.Sleep(10 * time.Second)     fmt.Println("可以了,通知監(jiān)控停止")     stop<- true     //為了檢測(cè)監(jiān)控過(guò)是否停止,如果沒(méi)有監(jiān)控輸出,就表示停止了     time.Sleep(5 * time.Second)  }

        例子中我們定義一個(gè)stop的chan,通知他結(jié)束后臺(tái)goroutine。實(shí)現(xiàn)也非常簡(jiǎn)單,在后臺(tái)goroutine中,使用select判斷stop是否可以接收到值,如果可以接收到,就表示可以退出停止了;如果沒(méi)有接收到,就會(huì)執(zhí)行default里的監(jiān)控邏輯,繼續(xù)監(jiān)控,只到收到stop的通知。

        以上是一個(gè) goroutine 的場(chǎng)景,如果是多個(gè) goroutine ,每個(gè)goroutine 底下又開(kāi)啟了多個(gè) goroutine 的場(chǎng)景呢?在 飛雪無(wú)情的博客 里關(guān)于為何要使用 Context,他是這么說(shuō)的

        chan+select的方式,是比較優(yōu)雅的結(jié)束一個(gè)goroutine的方式,不過(guò)這種方式也有局限性,如果有很多goroutine都需要控制結(jié)束怎么辦呢?如果這些goroutine又衍生了其他

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
        主站蜘蛛池模板: 国产精品最新国产精品第十页| 亚洲AV无码之日韩精品| 久久99精品国产99久久6| 国产成人精品免费视频大全麻豆| 一本大道无码日韩精品影视| 国产午夜精品久久久久九九电影| 国产亚洲精品国产| 午夜天堂精品久久久久| 久久精品无码专区免费| 国产精品婷婷午夜在线观看| 国产精品亚洲片在线va| 蜜芽亚洲av无码精品色午夜| 自拍偷在线精品自拍偷| 久久精品夜色噜噜亚洲A∨| 国产亚洲精品AA片在线观看不加载| 欧美日韩精品在线| 精品久久久久久亚洲| 99久久精品午夜一区二区 | 久久亚洲国产成人精品性色| 人妻少妇看A偷人无码精品| 国产亚洲精品影视在线产品| 国产成人精品免高潮在线观看 | 欧美日激情日韩精品| 久久99国产精品二区不卡| 国产精品1024香蕉在线观看| HEYZO无码综合国产精品227| 98视频精品全部国产| 97精品人妻系列无码人妻| 99精品国产自在现线观看| 大伊香蕉精品视频在线导航| 97久久精品国产精品青草| 99re热视频这里只精品| 国产精品亚洲片夜色在线| 欧美亚洲精品在线| 99久久99久久精品国产片果冻| 88久久精品无码一区二区毛片| 91精品国产品国语在线不卡| 尤物国产在线精品福利一区| 99视频在线精品国自产拍亚瑟| 88久久精品无码一区二区毛片 | 少妇精品无码一区二区三区|