- Go語言高級編程(第2版)
- 柴樹杉 曹春暉
- 707字
- 2025-08-07 17:56:14
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之間調度代價也很低,這些因素極大地促進了并發編程的流行和發?展。
- Learning Java Functional Programming
- Reporting with Visual Studio and Crystal Reports
- Objective-C Memory Management Essentials
- Vue.js入門與商城開發實戰
- Vue.js快跑:構建觸手可及的高性能Web應用
- HTML5+CSS3基礎開發教程(第2版)
- Python編程:從入門到實踐
- Android程序設計基礎
- WordPress 4.0 Site Blueprints(Second Edition)
- Android群英傳
- Hands-On Kubernetes on Windows
- C語言程序設計習題與實驗指導
- Mastering Gephi Network Visualization
- Ext JS 4 Plugin and Extension Development
- Visual C#(學習筆記)