Goroutine池

goroutine池的应用

  • 本质上是生产者消费者模型
  • 可以有效控制goroutine数量,防止暴涨
  • 需求:

    • 计算一个数字的各个位数之和,例如数字123,结果为1+2+3=6
    • 随机生成数字进行计算
  • 控制台输出结果如下:
job id: 164362 random: 3002688297310473558 result: 81
job id: 164363 random: 8188014692039052954 result: 84
job id: 164364 random: 9199514953162082256 result: 87
job id: 164365 random: 6547609431377245779 result: 96
job id: 164366 random: 5158862497998501304 result: 94
job id: 164367 random: 7591045689235318611 result: 84
job id: 164368 random: 4913457935486468007 result: 93
job id: 164369 random: 6484925446766292271 result: 94
job id: 164370 random: 1630566468428792798 result: 101
job id: 164371 random: 3999715154713986432 result: 96
job id: 164372 random: 8436839935373284876 result: 106
job id: 164373 random: 7590654756672405712 result: 88
job id: 164374 random: 5127823813978664887 result: 103
job id: 164375 random: 5630536624069526117 result: 77
job id: 164376 random: 3445557283367509019 result: 86
job id: 164377 random: 6087330610397339825 result: 83
job id: 164378 random: 3391465925899927215 result: 99

main.go

package main

import (
    "fmt"
    "math/rand"
)

type Job struct {
    Id int
    Random int
}

type Result struct {
    job *Job
    sum int
}

func createGoroutinePool(goNum int, jobChan chan *Job, resultChan chan *Result){
    // 根据goNum开启多个goroutine执行
    for i := 0; i < goNum; i++ {
        go func(jobChan chan *Job, resultChan chan *Result) {
            // 处理每个jobChan中的数据并返回结果
            for job := range jobChan{
                random := job.Random
                var sum int
                // 计算每一位的和
                for random != 0 {
                    tmp := random % 10
                    sum += tmp
                    random /= 10
                }
                // 组织返回结果
                r := &Result{
                    job: job,
                    sum: sum,
                }
                // 将结果写入通道
                resultChan<- r
            }
        }(jobChan, resultChan)
    }
}

func main() {
    // 工作通道
    jobChan := make(chan *Job, 128)
    // 结果通道
    resultChan := make(chan *Result,128)
    // 创建工作池执行任务
    createGoroutinePool(64, jobChan, resultChan)
    // 打印结果通道数据
    go func(resultChan chan *Result){
        for result := range resultChan{
            fmt.Printf("job id: %v random: %v result: %d\n", result.job.Id, result.job.Random, result.sum)
        }
    }(resultChan)

    var id int
    for {
        id++
        r_num := rand.Int()
        job := &Job{
            Id:     id,
            Random: r_num,
        }
        jobChan<-job
    }
}

你可能感兴趣的:(Goroutine池)