golang如何优雅的实现线程池
时间: 2023-07-17 21:55:43 浏览: 46
在 Golang 中,可以通过使用 `goroutine` 和 `channel` 来实现线程池。下面是一个示例代码:
```go
package main
import (
"fmt"
"sync"
)
type Job struct {
id int
}
type Result struct {
job Job
sum int
}
func worker(id int, jobs <-chan Job, results chan<- Result) {
for job := range jobs {
sum := 0
for i := 1; i <= job.id; i++ {
sum += i
}
results <- Result{job, sum}
}
}
func main() {
numJobs := 10
numWorkers := 3
jobs := make(chan Job, numJobs)
results := make(chan Result, numJobs)
// 创建并启动多个 worker
var wg sync.WaitGroup
for i := 1; i <= numWorkers; i++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
worker(workerID, jobs, results)
}(i)
}
// 添加任务到 jobs 通道
for i := 1; i <= numJobs; i++ {
jobs <- Job{i}
}
close(jobs)
// 处理结果
go func() {
wg.Wait()
close(results)
}()
// 输出结果
for result := range results {
fmt.Printf("Job ID: %d, Sum: %d\n", result.job.id, result.sum)
}
}
```
在上面的示例中,我们创建了一个 `Job` 结构来表示要执行的任务,并且创建了一个 `Result` 结构来存储任务的结果。然后,我们使用两个通道 `jobs` 和 `results` 分别来传递任务和结果。
我们创建了多个 worker 来处理任务,每个 worker 都会从 `jobs` 通道中接收任务,并将结果发送到 `results` 通道中。在主函数中,我们首先创建了 `jobs` 和 `results` 通道,并将所有的任务添加到 `jobs` 通道中。然后,我们使用 `sync.WaitGroup` 来等待所有的 worker 完成任务,并关闭 `results` 通道。最后,我们从 `results` 通道中读取结果并输出。
这样,就实现了一个简单且优雅的线程池。每个 worker 都可以并行处理任务,而无需手动管理 goroutine 的数量。