golang 實現一個簡單的協程池

1.what's goroutine poolgit

  當咱們有大量任務須要處理的時候,不想一會兒起太多goroutine影響主機性能。這時須要控制goroutine的總併發數。github

2.Example併發

  1.定義接口體性能

    Pool : 定義goroutine相關控制參數code

    Job:根據應用場景傳入須要處理的對象協程

    Work:加工處理Job對象對象

  2.定義任務處理方法blog

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()
}
相關文章
相關標籤/搜索