利用WaitGroup和Channel实现Go语言中的并发处理
package main
import (
"fmt"
"sync"
)
func worker(id int, wg *sync.WaitGroup, jobs <-chan int, results chan<- int) {
defer wg.Done() // 确保该goroutine在函数退出时通知WaitGroup
for job := range jobs {
// 模拟耗时工作
doWork(job)
results <- job * id // 将结果发送到results通道
}
}
func doWork(job int) {
// 模拟工作,这里仅仅是延迟
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
}
func main() {
var wg sync.WaitGroup
jobs := make(chan int, 100)
results := make(chan int, 100)
// 启动worker数量
const numWorkers = 3
// 添加等待的goroutines数量
wg.Add(numWorkers)
// 创建worker goroutines
for i := 0; i < numWorkers; i++ {
go worker(i, &wg, jobs, results)
}
// 发送工作到jobs通道
go func() {
for i := 0; i < 10; i++ {
jobs <- i
}
close(jobs) // 关闭jobs通道,通知所有worker它们都已收到所有任务
}()
// 收集结果
go func() {
wg.Wait() // 等待所有worker完成
close(results) // 工作完成,可以关闭results通道
}()
// 打印结果
for result := range results {
fmt.Println(result)
}
}
这段代码修复了原代码中的问题,并提供了一个更加健壮和有效的并发处理模型。它使用了sync.WaitGroup
来确保主goroutine等待所有工作完成,并使用了通道来在不同的goroutine之间安全地传递数据。通过这个例子,开发者可以学习到如何在Go语言中使用并发编程来提高程序的性能。
评论已关闭