Go 以其卓越的並發模型而聞名,但許多開發人員只專注於 goroutine 和通道。然而,工作池和扇出/扇入等並發模式提供了真正的效率。
本文將介紹這些進階概念,幫助您最大限度地提高 Go 應用程式的吞吐量。
並發允許程式有效率地執行任務,特別是在處理 I/O 操作、Web 請求或後台處理等任務時。在 Go 中,goroutines 提供了一種輕量級的方法來管理數千個並發任務,但如果沒有結構,您可能會遇到瓶頸。這就是工作池和扇出/扇入模式發揮作用的地方。
工作池允許您透過將任務指派給固定的「工作人員」來限制 goroutine 的數量。這可以防止超額訂閱,減少資源消耗,並使任務執行易於管理。
package main import ( "fmt" "sync" "time" ) func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) { defer wg.Done() for j := range jobs { fmt.Printf("Worker %d started job %d\n", id, j) time.Sleep(time.Second) // Simulate work fmt.Printf("Worker %d finished job %d\n", id, j) results <- j * 2 } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) var wg sync.WaitGroup // Start 3 workers for w := 1; w <= 3; w++ { wg.Add(1) go worker(w, jobs, results, &wg) } // Send jobs for j := 1; j <= 5; j++ { jobs <- j } close(jobs) // Wait for workers to finish wg.Wait() close(results) for result := range results { fmt.Println("Result:", result) } }
在此範例中:
扇出/扇入模式允許多個 goroutine 處理相同任務,而扇入則將結果收集回單一輸出。這對於劃分任務然後聚合結果非常有用。
package main import ( "fmt" "sync" "time" ) func workerFanOut(id int, tasks <-chan int, wg *sync.WaitGroup) { defer wg.Done() for task := range tasks { fmt.Printf("Worker %d processing task %d\n", id, task) time.Sleep(time.Second) // Simulate work } } func main() { var wg sync.WaitGroup tasks := make(chan int, 10) // Fan-out: Launch multiple workers for i := 1; i <= 3; i++ { wg.Add(1) go workerFanOut(i, tasks, &wg) } // Send tasks for i := 1; i <= 9; i++ { tasks <- i } close(tasks) // Wait for workers to finish wg.Wait() fmt.Println("All tasks are processed.") }
在上面的程式碼中:
並發模式可用於最佳化 Web 伺服器、批次系統或 I/O 密集型應用程式。使用工作池和扇出/扇出等模式可確保最佳的資源利用率,而不會壓垮系統容量。
增加知識的後續步驟:
- 探索如何將這些模式擴展到其他並發挑戰。
- 使用管理請求的工作池建立即時 Web 服務。
Go 並發成功的關鍵是結構。掌握這些並發模式將提高您的 Go 技能並幫助您編寫高效能應用程式。
請繼續關注下一篇文章,以了解更多關於 Go 的見解!
你可以買一本書給我:)
以上是Go 中的並發模式;工作池和扇出/扇入的詳細內容。更多資訊請關注PHP中文網其他相關文章!