并发模式
并发模式是指在并发编程中常用的设计模式和方法,用于有效地管理和协调多个并发任务。以下是一些常见的并发模式,结合 Go 语言的示例代码来介绍它们的应用。
1. 工作池(Worker Pool)
工作池模式通过一组固定数量的工作 Goroutine 来处理大量的任务,避免因为过多的 Goroutine 而导致资源的过度消耗。
package main
import (
"fmt"
"sync"
"time"
)
// Worker 函数,模拟处理任务
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) // 模拟工作
fmt.Printf("Worker %d finished job %d\n", id, j)
results <- j * 2 // 返回结果
}
}
func main() {
const numJobs = 5
const numWorkers = 3
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
var wg sync.WaitGroup
// 启动 worker Goroutine
for w := 1; w <= numWorkers; w++ {
wg.Add(1)
go worker(w, jobs, results, &wg)
}
// 发送任务到 jobs 通道
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
// 等待所有 worker 完成
wg.Wait()
close(results)
// 打印结果
for result := range results {
fmt.Println("Result:", result)
}
}
删除close(results)
语句会出现fatal error: all goroutines are asleep - deadlock!
错误
2. 扇入(Fan-in)
扇入模式将多个输入通道合并到一个通道,从而可以在单个 Goroutine 中处理来自多个来源的数据。
package main
import (
"fmt"
"time"
)
// generator 生成一系列数据并发送到通道
func generator(start int, end int, c chan<- int) {
for i := start; i <= end; i++ {
c <- i
time.Sleep(time.Millisecond * 500) // 模拟延迟
}
close(c)
}
// fanIn 将多个通道合并为一个通道
func fanIn(channels ...<-chan int) <-chan int {
out := make(chan int)
var wg sync.WaitGroup
output :=