
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中文網其他相關文章!