gopl-zh.github.com/ch9/ch9-08-1.md

1.6 KiB
Raw Blame History

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在跑爆內存之前可以創建多少流水線階段一個變量通過整個流水線需要用多久(這個練習題翻譯不是很確定。。)