您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Go語言怎么實現(xiàn)stop the world”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Go語言怎么實現(xiàn)stop the world”吧!
停止世界(Stop the world)
停止程序意味著停止所有正在運(yùn)行的 goroutine。下面是一個執(zhí)行 STW 的簡單程序:
func main() { runtime.GC() }
運(yùn)行垃圾回收器,將觸發(fā) STW 兩個階段。
有關(guān)垃圾回收器周期的更多信息,建議閱讀我的另外一篇文章 “Go:垃圾收集器如何標(biāo)記內(nèi)存? ① ”
第一步:搶占所有正在運(yùn)行的 goroutine:
goroutine 搶占
一旦 goroutine 被搶占,它們將在安全點(diǎn)停止。同時,P 處理器將(正在運(yùn)行的代碼或在空閑列表)被標(biāo)記為已停止,以不運(yùn)行任何代碼:
P 標(biāo)記為已停止
然后,Go 調(diào)度程序?qū)⑦\(yùn)行,將每個 M 與其 P 各自分離,并將其放入空閑列表中:
M 已移至閑置清單
關(guān)于在每個上運(yùn)行的 goroutine M,它們將在全局隊列中等待:
Goroutine 在全局隊列中等待
然后,一旦世界停止了,只有唯一活動的 goroutine 才能安全地運(yùn)行,并在工作完成后啟動整個世界。下面跟蹤圖將有助于理解此階段發(fā)生在何時:
跟蹤 “ STW”階段
系統(tǒng)調(diào)用
“STW”階段也可能會影響系統(tǒng)調(diào)用,因為它們可能會在 STW 時返回。讓我們以一個密集執(zhí)行系統(tǒng)調(diào)用的例子,并查看其如何處理:
func main() { var wg sync.WaitGroup wg.Add(10) for i := 0; i < 10; i++ { go func() { http.Get(`https://httpstat.us/200`) wg.Done() }() } wg.Wait() }
這是跟蹤:
STW 階段,系統(tǒng)調(diào)用正在結(jié)束。但是,由于沒有可用 P(如上一節(jié)所述,它們都被標(biāo)記為已停止),goroutine 將被放入全局隊列,并在世界恢復(fù)時稍后運(yùn)行。
延遲時間
“STW” 第三步涉及將所有 M 與其 P 分離。但是,Go 將等待它們自行停止:在調(diào)度程序運(yùn)行時,在 syscall 調(diào)用中等。等待 goroutine 被搶占應(yīng)該很快,但是在某些情況下,可能會導(dǎo)致某些延遲。讓我們以一個極端的情況為例:
func main() { var t int for i := 0;i < 20 ;i++ { go func() { for i := 0;i < 1000000000 ;i++ { t++ } }() } runtime.GC() }
在這里,“ Stop the World”階段需要 2.6 秒:
到此,相信大家對“Go語言怎么實現(xiàn)stop the world”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。