Goroutine池

394 阅读3分钟

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
     }
 }