golang 协程池

在这里插入图片描述

package main

import (
	"fmt"
	"time"
)

//---------------------------以下有关Task任务角色的功能
//定义一个任务类型 Task
type Task struct {
	function func() error //一个Task里面应该有一个具体的业务,业务名称叫function
}

//创建一个任务
func NewTask(arg_f func() error) *Task {
	t := Task{
		function: arg_f,
	}
	return &t
}

//Task也需要一个执行业务的方法
func (t *Task) Execute() {
	t.function() //调用任务已经绑定好的业务方法
}

//---------------------------以下有关协程池角色的功能

//定义一个Pool协程池类型
type Pool struct {
	//对外的Task入口 EntryChannel
	Entrychannel chan *Task
	//内部的Task队列 JobsChannel
	JobsChannel chan *Task
	//协程池中最大的协程数
	worker_num int
}

//创建一个Pool
func NewPool(cap int) *Pool {
	//创建一个Pool
	p := Pool{
		Entrychannel: make(chan *Task),
		JobsChannel:  make(chan *Task),
		worker_num:   cap,
	}
	return &p
}

//协程池创建一个worker,并让worker去工作
func (p *Pool) worker(worker_id int) {
	//一个worker的具体工作

	//永久的从JobsChannel去取任务
	for task := range p.JobsChannel {
		//task 就是当前worker从jobschannel中取到的任务
		//取到任务就执行
		task.Execute()
		fmt.Println("worker id ", worker_id, " 执行了一个任务")
	}
}

//让协程池开始真正的工作
func (p *Pool) run() {
	//根据worker_num 来创建worker去工作
	for i := 0; i < p.worker_num; i++ {
		go p.worker(i)
	}
	//不断从entrychannel中取任务,将取到的任务放到jobschannel中
	for task := range p.Entrychannel {
		//一旦入口有任务,放入jobschannel
		p.JobsChannel <- task
	}
}

//主函数 来测试协程池的工作
func main() {
	//创建一些任务
	t := NewTask(func() error {
		//当前任务的业务逻辑-匿名函数
		fmt.Println(time.Now())
		return nil
	})
	//创建协程池-协程数4
	p := NewPool(4000)

	task_num := 0
	//将这些任务交给协程池
	go func() {
		for {
			//不断的向P中写入任务
			p.Entrychannel <- t
			task_num += 1
			fmt.Println("当前一共执行了 ", task_num, " 个任务")
		}
	}()
	//启动Pool
	p.run()
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值