golang 实现一个简单的协程池

1.what's goroutine pool

  当我们有大量任务需要处理的时候,不想一下子起太多goroutine影响主机性能。这时需要控制goroutine的总并发数。

2.Example

  1.定义接口体

    Pool : 定义goroutine相关控制参数

    Job:根据应用场景传入需要处理的对象

    Work:加工处理Job对象

  2.定义任务处理方法

package main

import (
	"fmt"
	"github.com/labstack/gommon/log"
	"time"
)

type Pool struct {
	JobQueue	chan Job    	 // 带处理的任务数据
	WorkerCurrentNum     int       // 当前工作的协程数
	MaxWorker   int 		    // 最大工作协程数
	Result  chan bool
	FinishCallBack  func() error
}

type Job struct{
	ID int
}

type Worker struct {
	Result  chan bool
}

func (w *Worker) DoJob(job Job){
	fmt.Println(job.ID)
	time.Sleep(time.Second * 3)
	w.Result <- true
}


func (g *Pool) SetFinishCallBack(f func() error) {
	g.FinishCallBack  = f
}

// 往Job任务队列里面放入待处理的job
func (g *Pool) AddJob(job Job) {
	g.JobQueue <- job
}

// 开启协程池
func (g *Pool) Run() {
	go g.stop()
	for {
		if g.WorkerCurrentNum < g.MaxWorker {
			select {
			case job, ok := <-g.JobQueue:
				if ok {
					worker := &Worker{g.Result}
					go worker.DoJob(job)
					g.WorkerCurrentNum ++
				}else{
					log.Info("goroutine pool over")
					return
				}
			}
		}
	}
}

func (g *Pool) stop(){
	for {
		<- g.Result
		g.WorkerCurrentNum --
	}

}

func main() {
	jobQueue := make(chan Job)
	resultQueue := make(chan bool)

	p := &Pool{
		MaxWorker: 5,
		JobQueue: jobQueue,
		Result: resultQueue,
	}


	go func (){
		for i:=0; i<100;i++{
			job := Job{i}
			p.AddJob(job)
		}
		close(p.JobQueue)
	}()


	p.Run()
}

  

没有什么是写一万遍还不会的,如果有那就再写一万遍。
原文地址:https://www.cnblogs.com/waken-captain/p/9791038.html