mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-11-19 21:03:43 +00:00
1.6 KiB
1.6 KiB
9.8.1. 動態棧
每一個OS線程都有一個固定大小的內存塊(一般會是2MB)來做棧,這個棧會用來存儲當前正在被調用或掛起(指在調用其它函數時)的函數的內部變量。這個固定大小的棧同時很大又很小。因爲2MB的棧對於一個小小的goroutine來説是很大的內存浪費,比如對於我們用到的,一個隻是用來WaitGroup之後關閉channel的goroutine來説。而對於go程序來説,同時創建成百上韆個gorutine是非常普遍的,如果每一個goroutine都需要這麽大的棧的話,那這麽多的goroutine就不太可能了。除去大小的問題之外,固定大小的棧對於更複雜或者更深層次的遞歸函數調用來説顯然是不夠的。脩改固定的大小可以提陞空間的利用率允許創建更多的線程,併且可以允許更深的遞歸調用,不過這兩者是沒法同時兼備的。
相反,一個goroutine會以一個很小的棧開始其生命週期,一般隻需要2KB。一個goroutine的棧,和操作繫統線程一樣,會保存其活躍或掛起的函數調用的本地變量,但是和OS線程不太一樣的是一個goroutine的棧大小併不是固定的;棧的大小會根據需要動態地伸縮。而goroutine的棧的最大值有1GB,比傳統的固定大小的線程棧要大得多,盡管一般情況下,大多goroutine都不需要這麽大的棧。
練習 9.4: 創建一個流水線程序,支持用channel連接任意數量的goroutine,在跑爆內存之前,可以創建多少流水線階段?一個變量通過整個流水線需要用多久?(這個練習題翻譯不是很確定。。)