成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你覺得 Go 在什么時候會搶占 P?

開發(fā) 前端
Go 的調(diào)度器采用的是協(xié)作式調(diào)度為主,搶占式調(diào)度為輔。協(xié)作式調(diào)度意味著 Goroutine 需要主動放棄控制權(quán)來讓其他 Goroutine 運行,比如調(diào)用系統(tǒng)調(diào)用或者 Goroutine 自己調(diào)用 runtime.Gosched()。

在 Go 語言中,Goroutine 是并發(fā)模型的核心,而 P(Processor) 是 Go 調(diào)度器中的一個關(guān)鍵抽象。理解 Goroutine 調(diào)度模型 中的 G(Goroutine)、M(Machine,內(nèi)核線程)、P(Processor,邏輯處理器) 的關(guān)系可以幫助我們理解 Go 的搶占式調(diào)度策略。

Go 調(diào)度器使用 G-M-P 模型:

  • Goroutine (G):一個 Goroutine 代表一個 Go 協(xié)程。
  • Processor (P):P 是邏輯處理器,負責(zé)調(diào)度和管理 Goroutine,最多有 GOMAXPROCS 個 P。每個 P 可以運行一個 Goroutine。
  • Machine (M):M 是操作系統(tǒng)的內(nèi)核線程。每個 M 需要綁定一個 P 來執(zhí)行 Goroutine。

#Go 中的搶占式調(diào)度

Go 的調(diào)度器采用的是協(xié)作式調(diào)度為主,搶占式調(diào)度為輔。協(xié)作式調(diào)度意味著 Goroutine 需要主動放棄控制權(quán)來讓其他 Goroutine 運行,比如調(diào)用系統(tǒng)調(diào)用或者 Goroutine 自己調(diào)用 runtime.Gosched()。

搶占式調(diào)度則是為了防止某些 Goroutine 占用 CPU 太久(比如某個 Goroutine 在長時間執(zhí)行計算密集型任務(wù)),Go 1.14 引入了針對 計算密集型 Goroutine 的 搶占式調(diào)度。搶占式調(diào)度可以在以下場景下觸發(fā):

  • Goroutine 執(zhí)行時間過長,特別是沒有主動進行系統(tǒng)調(diào)用、調(diào)度讓出等行為時。
  • Goroutine 執(zhí)行在較長的函數(shù)調(diào)用鏈上,或者在一些函數(shù)的棧幀擴展時(例如深度遞歸調(diào)用或大數(shù)組操作時)。

#搶占 P 的時機

  1. 系統(tǒng)調(diào)用 (syscall) 后:當 Goroutine 執(zhí)行系統(tǒng)調(diào)用后,Goroutine 會讓出 P,此時調(diào)度器可能會選擇調(diào)度其他的 Goroutine 來運行。
  2. 垃圾回收 (GC) 階段:當觸發(fā)垃圾回收時,調(diào)度器會在合適時機搶占 Goroutine,確保 GC 可以進行。
  3. 計算密集型任務(wù)被長時間運行:從 Go 1.14 開始,調(diào)度器會定期檢查長時間運行的 Goroutine,并進行搶占。

#搶占式調(diào)度與長時間運行的 Goroutine

下面的例子展示了一個 Goroutine 在執(zhí)行計算密集型任務(wù)時如何可能會被 Go 的搶占式調(diào)度機制打斷。

package main

import (
	"fmt"
	"runtime"
	"time"
)

// 模擬一個計算密集型任務(wù)
func busyLoop() {
	for i := 0; i < 1e10; i++ {
		// 占用 CPU,但沒有主動讓出調(diào)度權(quán)
	}
	fmt.Println("Finished busy loop")
}

func main() {
	runtime.GOMAXPROCS(1) // 設(shè)置只有 1 個 P

	go func() {
		for {
			fmt.Println("Running another goroutine...")
			time.Sleep(500 * time.Millisecond) // 每 500 毫秒休息一次
		}
	}()

	busyLoop() // 執(zhí)行計算密集型任務(wù)

	time.Sleep(2 * time.Second)
}

#代碼解析:

  1. runtime.GOMAXPROCS(1):我們將 GOMAXPROCS 設(shè)置為 1,意味著整個程序中只有一個 P,這樣所有 Goroutine 都只能在這個 P 上調(diào)度。
  2. busyLoop:這是一個計算密集型任務(wù),在沒有主動進行系統(tǒng)調(diào)用或讓出調(diào)度權(quán)的情況下,循環(huán)執(zhí)行大量的操作,耗盡 CPU 時間。
  3. 搶占:雖然 busyLoop 沒有主動讓出 CPU,但由于 Go 的搶占式調(diào)度機制,調(diào)度器可能會在合適的時間點打斷 busyLoop,讓其他 Goroutine(比如打印 "Running another goroutine..." 的那個 Goroutine)得到執(zhí)行機會。

#輸出示例:

Running another goroutine...
Running another goroutine...
...
Finished busy loop

我們可以看到,盡管 busyLoop 是一個計算密集型任務(wù),其他的 Goroutine 仍然會間歇性地被調(diào)度并執(zhí)行。這個就是 Go 搶占式調(diào)度的效果。

#搶占的實現(xiàn)機制

搶占式調(diào)度的核心機制是 定期檢查 Goroutine 的執(zhí)行時間。Go 調(diào)度器在后臺維護一個時間戳,記錄 Goroutine 上次被調(diào)度的時間。調(diào)度器每隔一段時間會檢查當前運行的 Goroutine,如果 Goroutine 占用了 CPU 超過一定時間,調(diào)度器就會標記這個 Goroutine 需要被搶占,然后調(diào)度其他的 Goroutine 來執(zhí)行。

搶占式調(diào)度通過以下方式觸發(fā):

  1. 函數(shù)調(diào)用邊界:當 Goroutine 進行函數(shù)調(diào)用時,Go runtime 會在合適的時機插入搶占檢查點。
  2. 棧增長:當 Goroutine 的棧增長(如遞歸調(diào)用導(dǎo)致棧內(nèi)存增長)時,調(diào)度器也會插入搶占檢查。
  3. GC 安全點:垃圾回收過程中,調(diào)度器也會嘗試搶占。

#通過代碼觀察搶占效果

我們可以通過使用 GODEBUG 環(huán)境變量,啟用搶占式調(diào)度的調(diào)試日志,觀察搶占調(diào)度的具體行為。運行如下代碼時,啟用調(diào)試模式:

GODEBUG=schedtrace=1000,scheddetail=1 go run main.go
  • schedtrace=1000 表示每隔 1000 毫秒輸出一次調(diào)度器狀態(tài)。
  • scheddetail=1 表示輸出詳細的調(diào)度器信息。

#輸出內(nèi)容解釋

在輸出的調(diào)試信息中,我們可以看到調(diào)度器何時搶占了 Goroutine,何時讓出了 P,以及具體的調(diào)度行為。調(diào)試信息會包括如下內(nèi)容:

  • idle M:表示某個 M(線程)變成空閑狀態(tài)。
  • new work:表示調(diào)度器找到了新的工作,分配給 P。
  • steal work:表示調(diào)度器從其他 P 中竊取任務(wù)來運行。

#最后我們來總結(jié)一下

  • Go 的調(diào)度器主要基于 協(xié)作式調(diào)度,但是對于計算密集型任務(wù)會通過 搶占式調(diào)度 機制防止長時間占用 CPU。
  • 搶占調(diào)度在計算密集型 Goroutine、系統(tǒng)調(diào)用后、垃圾回收等場景下被觸發(fā)。
  • Go 1.14 引入了針對長時間運行的 Goroutine 的搶占式調(diào)度,使得 Goroutine 不會因為計算密集任務(wù)長時間阻塞 CPU。

這使得 Go 語言能更加高效地運行并發(fā)程序,避免單個 Goroutine 長時間霸占 CPU,影響其他 Goroutine 的執(zhí)行。

責(zé)任編輯:武曉燕 來源: Go語言圈
相關(guān)推薦

2021-04-19 09:20:01

Go 搶占 P語言

2021-09-29 09:24:21

GCGo STW

2023-06-06 16:54:00

2015-03-02 14:44:48

AngularJS jQuery超越

2021-03-23 10:08:02

編程互聯(lián)網(wǎng)數(shù)據(jù)科學(xué)

2025-02-28 09:04:08

2023-02-01 15:49:51

人工智能AI

2020-05-12 11:25:50

MySQLES數(shù)據(jù)庫

2017-05-15 09:55:07

2009-06-19 16:29:47

EJBXML

2015-07-08 15:55:01

NSStringcopystrong

2019-04-16 13:27:36

隱私數(shù)據(jù)信息保護

2013-11-28 16:03:24

2012-09-24 10:20:39

JavaScriptJS

2022-05-19 10:27:34

機器學(xué)習(xí)人工智能

2024-08-05 01:22:16

2017-06-28 15:06:51

PythonLambda函數(shù)

2022-09-08 09:42:26

JavaScripMapObject

2016-10-28 15:58:29

大數(shù)據(jù)就業(yè)成功率

2021-02-03 10:23:59

Wi-Fi 7Wi-Fi6數(shù)據(jù)速率
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 天天操夜夜爽 | 免费视频99| 日韩爱爱网站 | 日日夜夜草 | 色久五月 | 日韩中文字幕 | 一区二区三区不卡视频 | 日本三级日产三级国产三级 | 在线观看免费国产 | 国产三区视频在线观看 | 亚洲精品电影在线观看 | 99亚洲精品 | 日日夜夜操天天干 | 天天夜碰日日摸日日澡 | av香蕉| 国产一区视频在线 | 精品欧美一区二区三区久久久 | 国产精品欧美一区喷水 | 久久久久成人精品免费播放动漫 | 免费看黄色视屏 | 国产成人高清在线观看 | 国产一区精品在线 | 日韩国产在线 | 成人h免费观看视频 | 亚洲人在线 | 夜夜撸av | 91精品国产91久久久久游泳池 | 三级成人片 | 毛片免费观看 | 久久精彩视频 | 成人黄色在线 | 欧美多人在线 | 91啪亚洲精品 | 国产999精品久久久久久绿帽 | 欧美日韩在线免费 | 欧美日韩电影一区二区 | 国产一级片免费看 | 三级黄视频在线观看 | 国产精品一区二区免费看 | 视频一区二区三区四区五区 | 97精品国产一区二区三区 |