什麼是 Goroutine#
Goroutine 是 Go 的輕量級執行緒,由 Go 執行時期(Runtime)管理,而非作業系統。
func sayHello(name string) {
fmt.Println("Hello,", name)
}
func main() {
// 啟動 goroutine
go sayHello("World")
// 使用匿名函式
go func() {
fmt.Println("匿名 goroutine")
}()
// 等待 goroutine 完成(實際使用 sync.WaitGroup)
time.Sleep(time.Second)
}Goroutine 與 OS 執行緒的差異:
- Goroutine 初始堆疊只有 2KB(執行緒通常 1–8MB)
- 由 Go runtime 排程,切換成本極低
- 可以輕鬆建立數十萬個 goroutine
G-P-M 排程模型#
Go 排程器使用 G-P-M 模型:
- G(Goroutine):要執行的 goroutine
- P(Processor):邏輯處理器,預設數量等於 CPU 核心數
- M(Machine):作業系統執行緒
flowchart LR
subgraph Goroutines
G1[G1]
G2[G2]
G3[G3]
G4[G4]
G5[G5]
G6[G6]
end
subgraph Processors
P1[P1]
P2[P2]
end
subgraph OS Threads
M1[M1]
M2[M2]
end
G1 --> P1
G2 --> P1
G3 --> P1
G4 --> P2
G5 --> P2
G6 --> P2
P1 --> M1
P2 --> M2設定並行數量
import "runtime"
func main() {
// 查詢 CPU 核心數
numCPU := runtime.NumCPU()
// 設定可用的邏輯處理器數量
runtime.GOMAXPROCS(numCPU)
// Go 1.5+ 預設使用所有 CPU 核心
}生命週期#
func main() {
go worker() // 啟動 goroutine
// 主 goroutine 結束 → 程式立即終止
// 不會等其他 goroutine 完成!
}
func worker() {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(time.Millisecond * 100)
}
}
main函式回傳時,整個程式會立即終止,不會等其他 goroutine 完成。必須用適當的同步機制(WaitGroup、Channel)協調 goroutine。