Go 实现Goroutine Pool

在Go中应用goroutine池,一般是为了限制同时运行的goroutine数量,以避免资源过度消耗。goroutine池可以通过创建一个工作队列和一个固定数量的工作者来实现。以下是一个goroutine池的实现示例:

package main

import (
    "fmt"
    "time"
)

// Job 表示需要处理的任务
type Job struct {
    id       int
    workload int
}

// Worker 表示工作者
func Worker(id int, jobs <-chan Job, results chan<- int) {
    for job := range jobs {
        fmt.Printf("Worker %d processing job %d\n", id, job.id)
        time.Sleep(time.Duration(job.workload) * time.Second) // 模拟工作时间
        results <- job.id
    }
}

func main() {
    const numJobs = 5    // 总任务数
    const numWorkers = 3 // 工作者数

    jobs := make(chan Job, numJobs)   // 创建任务队列
    results := make(chan int, numJobs) // 创建结果队列

    // 启动工作者
    for w := range numWorkers {
        go Worker(w, jobs, results)
    }

    // 发送任务到任务队列
    for j := 0; j < numJobs; j++ {
        jobs <- Job{id: j, workload: j + 1}
    }
    close(jobs) // 关闭任务队列

    // 收集结果
    for a := 0; a < numJobs; a++ {
        result := <-results
        fmt.Printf("Job %d done\n", result)
    }
}
代码解析:
  1. Job结构体:表示一个任务,其中包含任务ID和工作负载(模拟任务所需的时间)。
  2. Worker函数:表示工作者,从jobs通道中获取任务并处理,然后将结果发送到results通道。
  3. jobs通道:用于分发任务给工作者。
  4. results通道:用于接收工作者完成任务后的结果。
执行过程:
  • 主函数中先创建了jobsresults两个通道。
  • 然后启动了一定数量的goroutine,每个goroutine都调用Worker函数并开始等待任务。
  • 主程序将任务发送到jobs通道,然后关闭通道以表示没有更多任务。
  • 最后,主程序等待从results通道接收所有任务的结果并输出。

通过这种方式,可以有效地控制同时运行的goroutine数量,避免系统资源过度消耗。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容