並發和 Goroutine
Go 的並發模型是其最顯著的特性之一,圍繞 goroutine 和 channel 的概念構建。與 JavaScript 的單線程事件循環或 C++ 的複雜線程模型不同,Go 提供了一種簡單而強大的並發編程方法,其座右銘是"不要通過共享記憶體來通信;要通過通信來共享記憶體"。
並發 vs 並行
並發是通過交錯執行來處理多個任務的能力,而並行是在不同 CPU 核心上同時執行多個任務的能力。
- JavaScript: 主要通過事件循環實現並發,通過 Web Workers 實現有限的並行
- Go: 既支援並發(goroutine)也支援並行(可以利用多個 CPU 核心)
Goroutine: 輕量級線程
Goroutine 是 Go 處理並發操作的方式。它們是由 Go 運行時管理的輕量級線程,而不是作業系統。
正在加载...
Goroutine 生命週期
創建 Goroutine
Goroutine 使用 go
關鍵字後跟函數調用來創建:
正在加载...
Goroutine 同步
與 JavaScript 基於 Promise 的同步不同,Go 使用 channel 和同步原語:
正在加载...
Channel: Goroutine 間的通信
Channel 是 Go 中 goroutine 間通信的主要機制。它們提供了一種安全的資料共享方式,無需顯式鎖定。
基本 Channel 操作
正在加载...
緩衝 vs 無緩衝 Channel
正在加载...
Select 語句
select
語句允許 goroutine 等待多個 channel 操作:
正在加载...
常見並發模式
工作池模式
正在加载...
管道模式
正在加载...
Goroutine 最佳實踐
1. 始終處理 Goroutine 生命週期
正在加载...
2. 避免 Goroutine 洩漏
正在加载...
性能考慮
Goroutine vs 線程對比
方面 | Goroutine | 作業系統線程 |
---|---|---|
記憶體 | ~2KB 棧 | ~1MB 棧 |
創建 | ~0.3μs | ~17μs |
上下文切換 | ~0.2μs | ~1.7μs |
並發數 | 百萬級 | 千級 |
何時使用 Goroutine
- I/O 密集型操作: 網路請求、檔案操作
- CPU 密集型操作: 數學計算(需要適當協調)
- 事件處理: 並發處理多個事件
- 後台任務: 清理、監控、日誌記錄
練習題:
- Go 中並發和並行有什麼區別?
- Goroutine 在資源使用方面與作業系統線程有何不同?
- 解釋緩衝 channel 和無緩衝 channel 的區別。
- 什麼時候使用
select
語句而不是簡單的 channel 接收? - 防止 goroutine 洩漏有哪些常見模式?
專案想法:
創建一個使用 goroutine 並發獲取多個 URL 的網路爬蟲,包含適當的錯誤處理和速率限制。爬蟲應該使用 channel 來協調工作線程並收集結果。