协程池的使用
func TestGoPool(t *testing.T) {
pool := utils.NewPool(3)
pool.Run()
time.Sleep(5*time.Second)
for i := 0; i < 100; i++ {
var param = make(map[string]interface{})
param["cc"] = i
task := &utils.Task{printString,param,true}
pool.InsertTask(task)
time.Sleep(5*time.Second)
}
pool.Stop()
}
func printString(param map[string]interface{}) {
for k, v := range param {
fmt.Println("key:",k,";value:",v)
}
}
协程池的代码
/*通道的单位*/
type Task struct {
//参数为map,无返回值的方法
TaskMethod func(param map[string]interface{})
TaskParam map[string]interface{}
RunFlag bool
}
/*定义池类型*/
type Pool struct {
//对外接收Task的入口
entryChannel chan *Task
//协程池最大worker数量,限定Goroutine的个数
worker_num int
//协程池内部的任务就绪队列
jobsChannel chan *Task
}
//创建一个协程池
func NewPool(cap int) *Pool {
p := Pool{
entryChannel: make(chan *Task, cap),
worker_num: cap,
jobsChannel: make(chan *Task, cap),
}
return &p
}
//让协程池Pool开始工作
func (p *Pool) Run() {
//首先根据协程池的数量限定,开启固定数量的协程执行任务,
for i := 0; i < p.worker_num; i++ {
go p.worker()
}
// 从EntryChannel协程池入口取外界传递过来的任务
// 并且将任务送进JobsChannel中
//for task := range p.entryChannel {
// p.jobsChannel <- task
//}
执行完毕关闭通道
//close(p.jobsChannel)
//close(p.entryChannel)
}
//协程池创建一个worker并且开始工作
func (p *Pool) worker() {
//不断的从JobsChannel内部任务队列中拿任务
for {
//如果拿到任务,则执行task任务
select {
case task:=<-p.entryChannel:
if task.RunFlag {
task.TaskMethod(task.TaskParam)
} else {
close(p.entryChannel)
return
}
//通道中没有任务的时候,
default:
fmt.Println("执行default")
time.Sleep(time.Duration(1)*time.Second)
}
}
}
func (p *Pool) InsertTask(t *Task) {
p.entryChannel <- t
}
//停止协程池
func (p *Pool) Stop() {
var f func(map[string]interface{})
for i := 0; i < p.worker_num; i++ {
p.entryChannel <- &Task{f, make(map[string]interface{}),false}
}
}