Go语言基础之Goroutine池
Go语言基础之goroutine池
简易的work pool
func worker(id int, jobs<-chan int, results chan<- int) {
for j := range jobs {
fmt.Printf("worker:%d start job:%d\n", id, j)
time.Sleep(time.Second)
fmt.Printf("worker:%d end job:%d\n", id, j)
results<- j * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// 开启3个goroutine
for w := 1; w<= 3; w++ {
go worker(w, jobs, results)
}
// 5个任务
for j := 1; j<= 5; j++ {
jobs<- j
}
close(jobs)
// 输出结果
for a := 1; a<= 5; a++ {
<-results
}
}
计算各个位数之和
- 本质上是生产者消费者模型
- 可以有效控制goroutine数量,防止暴涨
- 需求:
- 计算一个数字的各个位数之和,例如数字123,结果为1+2+3=6
- 随机生成数字进行计算
package main
import (
"fmt"
"math/rand"
)
type Job struct {
// id
Id int
// 需要计算的随机数
RandNum int
}
type Result struct {
// 这里必须传对象实例
job *Job
// 求和
sum int
}
func main() {
// 需要2个管道
// 1.job管道
jobChan := make(chan *Job, 128)
// 2.结果管道
resultChan := make(chan *Result, 128)
// 3.创建工作池
createPool(64, jobChan, resultChan)
// 4.开个打印的协程
go func(resultChan chan *Result) {
// 遍历结果管道打印
for result := range resultChan {
fmt.Printf("job id:%v randnum:%v result:%d\n", result.job.Id,
result.job.RandNum, result.sum)
}
}(resultChan)
var id int
// 循环创建job,输入到管道
for {
id++
// 生成随机数
r_num := rand.Int()
job := &Job{
Id: id,
RandNum: r_num,
}
jobChan <- job
}
}
// 创建工作池
// 参数1:开几个协程
func createPool(num int, jobChan chan *Job, resultChan chan *Result) {
// 根据开协程个数,去跑运行
for i := 0; i < num; i++ {
go func(jobChan chan *Job, resultChan chan *Result) {
// 执行运算
// 遍历job管道所有数据,进行相加
for job := range jobChan {
// 随机数接过来
r_num := job.RandNum
// 随机数每一位相加
// 定义返回值
var sum int
for r_num != 0 {
tmp := r_num % 10
sum += tmp
r_num /= 10
}
// 想要的结果是Result
r := &Result{
job: job,
sum: sum,
}
//运算结果扔到管道
resultChan <- r
}
}(jobChan, resultChan)
}
}
- 控制台输出结果如下:
在当下的阶段,必将由程序员来主导,甚至比以往更甚。