官术网_书友最值得收藏!

1.5.1 goroutine和系統線程

goroutine是Go語言特有的并發體,是一種輕量級的線程,由go關鍵字啟動。在真實的Go語言實現中,goroutine和系統線程不是等價的。盡管兩者的區別實際上只是一個量的區別,但正是這個量變引發了Go語言并發編程質的飛?躍。

每個系統線程都會有一個固定大小的棧(一般默認是2 MB),這個棧主要用來保存函數遞歸調用時的參數和局部變量。固定棧的大小導致了兩個問題:對于很多只需要小的棧空間的線程,這是一種巨大的浪費;對于少數需要巨大棧空間的線程,這又增大了棧溢出的風險。針對這兩個問題,要么減小固定的棧大小,提升空間的利用率,要么增大棧的大小以允許更深的函數遞歸調用,但這兩者是無法兼得的。而goroutine可以以一個很小的棧啟動(可能是2 KB或4 KB),當遇到深度遞歸導致當前棧空間不足時,goroutine會根據需要動態地伸縮棧的大小(主流實現中棧的最大值可達到1 GB)。因為啟動的代價很小,所以我們可以輕易地啟動成千上萬個goroutine。

Go語言的運行時還包含了其自己的調度器,這個調度器使用了一些技術手段,可以在n個操作系統線程上多工調度m個goroutine。Go調度器的工作原理和內核的調度是相似的,但是這個調度器只關注單獨的Go程序中的goroutine。在Go 1.14之前,goroutine采用的是半搶占式的協作調度,只有在當前goroutine發生阻塞時才會導致調度;調度發生在用戶態,調度器會根據具體函數只保存必要的寄存器,切換的代價要比系統線程低得多。Go 1.14開始支持goroutine異步搶占調度,通過操作系統的信號機制讓運行goroutine的底層系統線程進入休眠模式,從而完成調度工作。此外,運行時有一個runtime.GOMAXPROCS變量,用于控制當前正常非阻塞運行goroutine的系統線程數?目。

在Go語言中啟動一個goroutine不僅和調用函數一樣簡單,而且在goroutine之間調度代價也很低,這些因素極大地促進了并發編程的流行和發?展。

主站蜘蛛池模板: 罗源县| 建阳市| 定兴县| 阜城县| 惠东县| 康乐县| 清涧县| 普宁市| 尼木县| 关岭| 台湾省| 九龙坡区| 金塔县| 永昌县| 靖边县| 赣州市| 天津市| 喀什市| 十堰市| 武隆县| 蒙自县| 平凉市| 宜春市| 娱乐| 慈利县| 辽源市| 黔西县| 土默特左旗| 和平区| 宜黄县| 博客| 土默特右旗| 阳江市| 伊宁县| 威远县| 尼勒克县| 金溪县| 泌阳县| 嘉黎县| 丰台区| 庄浪县|