要求:利用生产者消费者实现对一个随机数所有位求和(体现结构体与通道)
实现:
item结构体存储id与一个随机数,itemChan作为通道存储item结构体
result结构体存储item指针与对item的num随机数所有位求和的结果,resultChan作为通道存储result结构体
启动两个生产者,利用函数实现自定义启动n个消费者,关键是最后的printResult函数,与通道交流时同时阻塞了main,防止main的结束迫使所有goroutine结束。
package main
import (
"fmt"
"math/rand"
)
var itemChan chan *item //存放待求和结构体的通道
var resultChan chan *result //存放求和结果结构体的通道
//待求和结构体
type item struct {
id int64
num int64
}
//求和结果结构体
type result struct {
item *item
sum int64
}
//生产者,初始化待求和结构体,存入*item类型通道
func producer(ch chan *item) {
//1.生成随机数
var id int64
for {
id++
number := rand.Int63() //int64正整数
tmp := &item{
id: id,
num: number,
}
//2.把随机数所在结构体发送到通道
ch <- tmp
}
}
//计算一个数字所有位之和
func calc(num int64) int64 {
//将num模10后再除以10
// 123%10=12...3
// 12%10=1...2
// 1%10=0...1
var sum int64
for num > 0 {
sum += num % 10
num = num / 10
}
return sum
}
//消费者,从*item类型通道取值处理,利用结果来初始化求和结果结构体,存入*result类型通道
func consumer(itemCh chan *item, resultChan chan *result) {
for tmp := range itemCh {
sum := calc(tmp.num)
//构造结果结构体result
rstObj := &result{
item: tmp,
sum: sum,
}
resultChan <- rstObj
}
}
//go运行多个消费者
func startMultiConsumer(n int, itemCh chan *item, rstChan chan *result) {
for i := 0; i < n; i++ {
go consumer(itemCh, rstChan)
}
}
//打印求和结果通道里的数据
func printResult(rstChan chan *result) {
for rst := range rstChan {
fmt.Printf("id:%v, num:%v, sum:%v\n", rst.item.id, rst.item.num, rst.sum)
}
}
func main() {
itemChan = make(chan *item, 1000)
resultChan = make(chan *result, 10)
go producer(itemChan)
go producer(itemChan)
//开启50个消费者
startMultiConsumer(50, itemChan, resultChan)
//打印结果,顺便阻塞main,让其他goroutine完成工作。否则main结束,其他goroutine就被强行结束
printResult(resultChan)
}