Go 并发实例之求和

实现一个并发求和

我们利用并发的特性将自然数从0-100,分成N组,然后并发求和,最后汇总。 实现逻辑大概如下:

  1. 把100个数等份分成N组,构建了10个待计算的任务。
  2. 启动M个协程去计算N组数据
  3. 等待所有都完成之后,统计最后的结果

代码实例:

package main

import (
	"fmt"
)

//实现一个并发求和

//把100个数等份分成N组,构建了10个待计算的任务。
//启动M个协程去计算N组数据
//等待所有都完成之后,统计最后的结果

const (
	WORKERS_COUNT = 2
)

//任务的数据结构
type task struct {
	begin int
	end int
	result chan<- int
}

func (t task) do()  {
	sum := 0
	for i :=t.begin;i<t.end;i++{
		sum +=i
	}
	t.result <-sum
}

//构建任务队列
func buildTask(taskChan chan <- task,resultChan chan<- int,count int)  {
	group := count/10
	mod := count%10
	if mod !=0{
		group +=1
	}
	for i :=0;i<group;i++{
		end := (i+1)*10
		if end >count{
			end = count
		}
		tsk := task{
			begin: i *10,
			end: end,
			result: resultChan,
		}
		taskChan <- tsk
	}
	close(taskChan)
}

//分发任务队列
func distributeTask(taskChan <- chan task,workers int,done chan <- struct{})  {
	for i :=0;i<workers;i++{
		go workerTask(taskChan,done)
	}
}

//计算任务
func workerTask(taskChan <- chan task,done chan <- struct{})  {
	for v:= range taskChan{
		v.do()
		done<- struct{}{}
	}
}

//等待所有的任务完成
func closeResult(done chan struct{},resultChan chan <-int,workers int)  {
	for i :=0;i<workers;i++{
		<-done
	}
	close(done)
	close(resultChan)
}

//汇总结果
func processResult(resultChan <-chan int) int{
	sum :=0
	for v:= range resultChan{
		sum +=v
	}
	return sum
}

func main() {
	workers := WORKERS_COUNT
	count:=100

	//任务列表
	taskChan := make(chan task,10)

	//结果列表
	resultChan := make(chan int,10)

	//结果通知
	done := make(chan struct{},10)

	//生成任务列表
	go buildTask(taskChan,resultChan,count)

	go distributeTask(taskChan,workers,done)

	closeResult(done,resultChan,workers)

	sum:= processResult(resultChan)
	fmt.Println("sum=",sum)
}

  

posted @ 2021-01-25 14:48  pebblecome  阅读(444)  评论(0)    收藏  举报