golang 個人筆記和心得

goroutine

在講goroutine之前, 必須先了解 concurrency 和 parllelism的不同

concurrency (併發) vs parallelism (並行)

併發 concurrency 是將 process 切割成多個可執行單位(coroutine), 如果有多個 process 時則在 coroutine 中交互執行, 這樣不會因為某一個 process 執行太久造成其他 process 無法處理, 會讓你有多工的感覺. 但這並不會增加執行效率. 總執行時間是一樣的, 如圖一所示. 另外和 thread 不同的是, thread 是屬於 os 層面上的, 且 thread 非常消耗系統資源.

並行 parallelism 是多個 process 由多個 cpu 去執行, 可以增加執行的效率, 縮短總執行的時間. 如圖二所示

goroutine

go 用 goroutine 實現了 concurrency. 使用者只要設定最大的 thread 數量, 和系統是多少CPU, run-time 就會幫你處理好剩下的 thread 管理, 但為什麼 gorountine 可以提供較好的效能? (以下為個人心得可能有錯)

第一. 在創造 goroutine 的資源消耗是很小的, 因為 goroutine 只是一個 function 的入口. 只要很小的 stack 去記錄即可.

第二. thread 上的管理, 當某個 goroutine 被 block 住, 處理此 goroutine 的 thread 就耗在這上, 此時 run-time 會將其他的 goroutine 轉給此 thread 去執行, 這樣 thread 就不會因為執行某些被 block 的任務則消耗在那邊. 有效的使用 thread.

第三. thread 最多不會超過 $GOMAXPROCS(使用者設定的), 可以確保 thread 不會失控的增加.

綜合以上三點, goroutine 其實就是避免 thread 的不當增加, 有效的使用目前的 thread , 這樣系統資源的消耗就少了. 不會因為系統的資源不夠造成整體效能的降低.

reference :

coroutine 資料一

coroutine 資料二

thread 資料

goroutine 資料一

goroutine 資料二

goroutine 資料三

官網對 goroutine 的描述

Goroutines are part of making concurrency easy to use. The idea, which has been around for a while, is to multiplex independently executing functions—coroutines—onto a set of threads. When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked. The programmer sees none of this, which is the point. The result, which we call goroutines, can be very cheap: they have little overhead beyond the memory for the stack, which is just a few kilobytes.

To make the stacks small, Go's run-time uses resizable, bounded stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time grows (and shrinks) the memory for storing the stack automatically, allowing many goroutines to live in a modest amount of memory. The CPU overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number.