golang并发控制代码 大伟注释

package main

import (
	"fmt"
	"time"
)

type GoPool struct {
	MaxLimit int
	tokenChan chan struct{}
}

// 定义一个函数类型(这个函数有一个入参没有返回值)
type GoPoolOption func(*GoPool)

// 动态生成一个函数,这里我将这个函数命名为并发控制函数(生成的这个函数有如下函数体:重新初始化结构体值’并发个数,令牌通道内存,通道槽位赋值‘)
func WithMaxLimit(max int) GoPoolOption {
	return func(gp *GoPool){
		gp.MaxLimit = max
		gp.tokenChan = make(chan struct{},gp.MaxLimit)

		for i:=0;i<gp.MaxLimit;i++{
			gp.tokenChan <- struct{}{}
		}
	}
}

// 将并发控制函数做成参数传递给New函数,使用New函数生成一个运行池。
func NewGoPool(options ...GoPoolOption) *GoPool {
	p := &GoPool{}
	for _,o := range  options{
		o(p)
	}
	return p
}
//1、先初始化一个运行池,默认0值。
//2、在用并发控制函数对这个运行池进行规则初始化(:重新初始化结构体值’并发个数,令牌通道内存,通道槽位赋值‘)。
//3、返回这个运行池。

// 并发提交一个任务
func (gp *GoPool) Submit(fn func()){
	token := <- gp.tokenChan //取到了牌子,才能去开启一个任务
	go func(){                 //并发
		fn()                   //执行任务
		gp.tokenChan <- token  //任务执行完了,还回牌子
	}()
}
// 为运行池添加Wait方法,其实我认为这个方法更合适的名字是:关闭通道 (即此方法的功能是:在每个槽位都空闲的时候关闭通道)
func (gp *GoPool) Wait(){
	for i:=0 ;i<gp.MaxLimit;i++{  //只是在关闭通道之前,需要想能取到每个槽位的令牌,而要取到每个槽位的令牌就需要每个槽位都空闲。
		<- gp.tokenChan
	}
	close(gp.tokenChan)
}

// 通道到槽位里面有几个槽位有令牌(有值)?
func (gp *GoPool) size() int {
	return len(gp.tokenChan)
}

func main() {
	gopool := NewGoPool(WithMaxLimit(1), WithMaxLimit(4))
	defer gopool.Wait()

	for i:=0;i<5;i++ {
		fmt.Println("每个任何开启之前通道的大小:",gopool.size())
		gopool.Submit(func() {
			fmt.Println("qian",gopool.size())
			time.Sleep(2 * time.Second)
			fmt.Println(time.Now())
			fmt.Println("hou",gopool.size())
		})
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值