写一个 goroutine 实例, 同时练习一下 chan

简述

本质上是生产者消费者模型

  • 通过控制goroutine数量,防止暴涨
  • 需求:
    – 计算一个数字的各个位数之和,例如数字123,结果为1+2+3=6
    – 随机生成数字进行计算

代码:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 生产者
type Job struct {
	Id      int // 编号
	RandNum int // 产生的随机值
}

// 消费者
type Result struct {
	job *Job // 传入对象实例	why?
	sum int  // 求和值
}

// 创建工作池
// 参数1: 开几个协程
func createPool(num int, jobChan chan *Job, resultChan chan *Result) {
	// 根据协程个数 去运行
	for i := 0; i < num; i++ {
		go func(jC chan *Job, rC chan *Result) {
			// 执行运算
			// 遍历 job 管道所有数据,进行相加
			for job := range jC {
				// 随机数接过来
				r_num := job.RandNum

				// 随机数每一位相加
				// sum 位数求和返回值
				var sum int = 0
				for r_num != 0 {
					tmp := r_num % 10
					sum += tmp
					r_num /= 10
				}

				// 想要结果放入 Result
				r := &Result{
					job: job,
					sum: sum,
				}
				// 运算结果 给 chan
				rC <- r
			}
		}(jobChan, resultChan)
	}
}

func main() {
	// 需要 2 个chan用来传入数 和 求值
	// 1. job 管道
	jobChan := make(chan *Job, 128)
	// 2. result 管道
	resultChan := make(chan *Result, 128)

	// 3. 创建工作池
	createPool(64, jobChan, resultChan)

	// 4. 利用 goroutine 打印数据
	go func(ch chan *Result) {
		// 遍历结果管道打印
		for result := range ch {
			fmt.Printf("job id: %v\trandnum: %v\tresult: %v\n", result.job.Id,
				result.job.RandNum, result.sum)
		}
	}(resultChan)

	var id int = 0
	var count int = 20 //只计算 20 组数据
	// 循环创建 job, 输入到管道
	for count > 0 {
		
		time.Sleep(time.Second) // 不然协程运行20次太快
		count--
		id++

		// 生成随机数
		r_num := rand.Int() // 这里是生成一个非负的数, [0, 2^64)
		job := &Job{
			Id:      id,
			RandNum: r_num,
		}
		jobChan <- job

	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值