Goroutine(協程)為何能處理大併發?

2022-06-10 05:06:06 字數 871 閱讀 6131

簡單來說:協程十分輕量,可以在乙個程序中執行有數以十萬計的協程,依舊保持高效能。

程序、執行緒、協程的關係和區別:

堆和棧的區別請參看:

協程和執行緒的區別是:協程避免了無意義的排程,由此可以提高效能,但也因此,程式設計師必須自己承擔排程的責任。

執行協程只需要極少的棧記憶體(大概是4~5kb),預設情況下,執行緒棧的大小為1mb。

goroutine就是一段**,乙個函式入口,以及在堆上為其分配的乙個堆疊。所以它非常廉價,我們可以很輕鬆的建立上萬個goroutine,但它們並不是被作業系統所排程執行。

和所有其他併發框架裡的協程一樣,goroutine裡所謂「無鎖」的優點只在單執行緒下有效,如果$gomaxprocs > 1並且協程間需要通訊,go執行庫會負責加鎖保護資料,這也是為什麼sieve.go這樣的例子在多cpu多執行緒時反而更慢的原因.

goroutine 的乙個主要特性就是它們的消耗;建立它們的初始記憶體成本很低廉(與需要 1 至 8mb 記憶體的傳統 posix 執行緒形成鮮明對比)以及根據需要動態增長和縮減占用的資源。這使得 goroutine 會從 4096 位元組的初始棧記憶體占用開始按需增長或縮減記憶體占用,而無需擔心資源的耗盡。

為了實現這個目標,鏈結器(5l、6l 和 8l)會在每個函式前插入乙個序文,這個序文會在函式被呼叫之前檢查判斷當前的資源是否滿足呼叫該函式的需求(備註 1)。如果不滿足,則呼叫 runtime.morestack 來分配新的棧頁面(備註 2),從函式的呼叫者那裡拷貝函式的引數,然後將控制權返回給呼叫者。此時,已經可以安全地呼叫該函式了。當函式執行完畢,事情並沒有就此結束,函式的返回引數又被拷貝至呼叫者的棧結構中,然後釋放無用的棧空間。

通過這個過程,有效地實現了棧記憶體的無限使用。假設你並不是不斷地在兩個棧之間往返,通俗地講叫棧分割,則代價是十分低廉的。

Goroutine(協程)為何能處理大併發

簡單來說 協程十分輕量 可以在乙個程序中執行有數以十萬計的協程,依舊保持高效能。程序 執行緒 協程的關係和區別 堆和棧的區別請參看 協程和執行緒的區別是 協程避免了無意義的排程,由此可以提高效能,但也因此,程式設計師必須自己承擔排程的責任。執行協程只需要極少的棧記憶體 大概是4 5kb 預設情況下,...

GO 協程池 Goroutine復用 限制數量

建立乙個協成復用,限制協成數量的協成池 package pool import fmt type pool inte ce type pool struct 計數,限制協成數 func new size int pool size func p pool schedule task func err...

Python下對協程的處理

所謂協程又稱為微執行緒,我們在程序在建立時,需要耗費時間和cpu資源 在建立多執行緒時,也需要消耗時間和資源。利用多協程的執行過程中,始終只要乙個執行緒,不存在建立執行緒和銷毀執行緒需要的時間 也沒有執行緒切換的開銷,任務需要開啟執行緒數越多,協程的優勢越明顯 更不需要多執行緒的鎖機制 gil im...