[英]Goroutine works even I set runtime.GOMAXPROCS(1). Why?
[英]Golang: why runtime.GOMAXPROCS is limited to 256?
我在MacBook和Ubuntu上使用golang 1.7.3,發現runtime.GOMAXPROCS限制為256。有人知道此限制來自何處嗎? 是否在任何地方都有記錄,為什么會有限制? 這是實現優化嗎?
在此頁面上,我僅能找到256個參考,該參考描述了golang的運行時軟件包: https ://golang.org/pkg/runtime/。 runtime.MemStats結構具有幾個大小為256的狀態數組:
type MemStats struct {
...
PauseNs [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
PauseEnd [256]uint64 // circular buffer of recent GC pause end times
這是我使用的示例golang代碼:
func main() {
runtime.GOMAXPROCS(1000)
log.Printf("GOMAXPROCS %d\n", runtime.GOMAXPROCS(-1))
}
打印GOMAXPROCS 256
PS另外,有人可以指出我有關此GOMAXPROCS與golang調度程序使用的OS線程計數的關系的文檔(如果有的話)。 我們是否可以觀察到運行GOMAXPROCS OS線程的經過編譯的代碼?
編輯:感謝@twotwotwo指出GOMAXPROCS如何與OS線程相關。 仍然很有趣的是,文檔沒有提到這個256的限制(除了在MemStats結構中可能或可能不相關的限制)。
我想知道是否有人知道這256個數字的真正原因。
軟件包runtime
文檔闡明了GOMAXPROCS與OS線程的關系:
GOMAXPROCS變量限制了可以同時執行用戶級Go代碼的操作系統線程的數量。 對於代表Go代碼的系統調用中可以阻止的線程數量沒有限制; 那些不計入GOMAXPROCS限制。 該軟件包的GOMAXPROCS函數查詢並更改限制。
因此,您可能會看到不止一個GOMAXPROCS OS線程(因為某些線程在系統調用中被阻塞,並且對數量沒有限制),或者更少(因為GOMAXPROCS僅被記錄為限制線程數,而沒有確切地規定它)。
我認為限制GOMAXPROCS符合該文檔的精神-您指定可以運行1000個運行Go代碼的OS線程是可以的,但是運行時決定“僅”運行256個。這不會限制激活的goroutine的數量,因為它們當一個goroutine塊(例如,等待網絡讀取完成)時,Go的內部調度程序將在同一OS線程上啟動其他工作。
Go團隊可能會選擇這種方法,以最大程度地減少Go程序最終運行的OS線程的機會是當今大多數具有內核的機器的幾倍; 這將導致更多的OS上下文切換,這可能比如果將GOMAXPROCS保持在現有CPU內核數量以下而進行的用戶模式goroutine切換要慢。 或者,對於設計Go的內部調度程序來說,在GOMAXPROCS上設置上限可能只是很方便。
Goroutines vs Threads並不完美,例如goroutines現在還沒有分段堆棧,但是它可以幫助您了解引擎蓋下的情況。
請注意,從下一個Go 1.10(Q1 2018)開始, GOMAXPROCS
將受到...的限制。
運行時不再人為地限制
GOMAXPROCS
(以前僅限於1024)。
請參閱Austin Clements( aclements
)的 ee55000提交 ,該版本修復了問題15131 。
既然
allp
是動態分配的,那么就不需要對GOMAXPROCS
設置硬上限了。
參見commit e900e27 :
runtime
:清理allp
循環現在,
allp
長度為gomaxprocs
,這意味着allp[i]
都不為nil或不處於_Pdead
狀態。
這樣就可以用正常范圍循環替換allp上幾種不同樣式的循環。
for i := 0; i < gomaxprocs; i++ { ... }
for i := 0; i < gomaxprocs; i++ { ... }
循環可以簡單地遍歷allp
。
同樣,range loops over allp[:gomaxprocs]
可以在allp
范圍allp
。檢查
p == nil || p.state == _Pdead
循環p == nil || p.state == _Pdead
不再需要檢查。如果失效的P不影響
p == nil
,則檢查p == nil
循環不必進行檢查。 我檢查了所有這些循環,實際上都不受死P的影響。 可能會影響一個循環,這可以通過將p.gcAssistTime
為procresize
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.