langShift

並發和 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 密集型操作: 數學計算(需要適當協調)
  • 事件處理: 並發處理多個事件
  • 後台任務: 清理、監控、日誌記錄

練習題:

  1. Go 中並發和並行有什麼區別?
  2. Goroutine 在資源使用方面與作業系統線程有何不同?
  3. 解釋緩衝 channel 和無緩衝 channel 的區別。
  4. 什麼時候使用 select 語句而不是簡單的 channel 接收?
  5. 防止 goroutine 洩漏有哪些常見模式?

專案想法:

創建一個使用 goroutine 並發獲取多個 URL 的網路爬蟲,包含適當的錯誤處理和速率限制。爬蟲應該使用 channel 來協調工作線程並收集結果。