Go 語言的并發模型是其最顯著的語言特性之一。Goroutine 是 Go 實現并發的核心機制,它比線程更輕量,調度效率極高。
本章將帶你了解 Goroutine 的基本概念、創建方式以及背后的調度機制。
一、什么是 Goroutine?
Goroutine 是由 Go 運行時(runtime)管理的輕量級線程。
特點:
- ? 啟動快:創建成本遠小于線程
- ? 占用小:初始棧大小僅約 2 KB,按需增長
- ? 數量多:支持成千上萬個 Goroutine 并發運行
- ? 自動調度:由 Go runtime 自動調度到多個線程上執行
二、創建 Goroutine
創建一個 Goroutine 非常簡單,只需使用?go
?關鍵字:
func?sayHello()?{fmt.Println("Hello?from?Goroutine")
}func?main()?{go?sayHello()?//?啟動一個新的?Goroutinefmt.Println("Main?function")time.Sleep(time.Second)?//?等待子協程執行完畢
}
運行效果(輸出可能順序不定):
Main?function
Hello?from?Goroutine
注意:主 Goroutine 退出時,程序將直接終止,其他 Goroutine 即使未完成也會被強制結束。
三、匿名函數啟動 Goroutine
可以使用匿名函數快速創建 Goroutine:
go?func(name?string)?{fmt.Println("Hello,",?name)
}("Go")
四、Goroutine 的調度模型
Go 使用M:N 調度模型:
- ??M(Machine):操作系統線程(OS Thread)
- ??G(Goroutine):用戶級協程
- ??P(Processor):邏輯處理器,調度器的核心
調度器作用:
- ? 把成千上萬個 G 映射到有限的 M 上
- ? 利用 P 控制并發度(由?
GOMAXPROCS
?控制)
你可以通過設置?GOMAXPROCS
?控制最大并發線程數:
runtime.GOMAXPROCS(2)
默認值為當前機器 CPU 核數。
五、調度器工作方式簡要流程
- 1. 創建 Goroutine 后,進入可運行隊列
- 2. 調度器從隊列中取出 Goroutine 并分配給線程執行
- 3. 阻塞操作(如 IO)會讓線程掛起并調度其他 Goroutine
- 4. 非搶占式調度 + 安全點機制(某些點才能切換)
六、調試與觀察 Goroutine
可以使用?runtime
?包查看當前 Goroutine 數量:
fmt.Println("Goroutine數量:",?runtime.NumGoroutine())
使用?go tool pprof
?或第三方工具(如 delve)分析 Goroutine 狀態。
七、使用場景舉例
- ? 高并發 Web 服務器處理請求
- ? 定時任務并發執行
- ? 異步日志寫入
- ? 并發爬蟲
八、小結
特性 | 說明 |
創建方式 | 使用?go ?關鍵字 |
性能 | 數量輕量、棧空間動態增長 |
調度機制 | M:N 多對多調度,由 runtime 管理 |
并發優勢 | 快速、高效、代碼簡潔 |