自制golang并发处理小框架

并发

通过channel、互斥锁、定时器三者结合,完成了一个并发处理的函数接口。

  • 通过传入协程池数、超时时间来限制协程的并发处理(协程池的数量应该小于数据循环处理的次数)。
  • 参数中指定待处理的数据以及循环的次数,以及注册回调函数来处理自己的数据。如果传入的参数是数组,那么在回调函数中通过协程调用的索引号即可判断需要处理的是第几个元素。
type HanleParam struct {
	Data interface{} `comment:"待处理的数据,会传入回调函数中"`
	Num  int         `comment:"调用协程的次数"`
	Mx   *sync.Mutex `comment:"互斥锁"`
}

/*
* param:
* 	@ maxGoNum 协程最大数量
* 	@ timeout 超时时间
*	@ handle 回调处理方法
* 	@ param 待处理的参数
 */
func GoHandle(
	maxGoNum int, timeout time.Duration,
	handle func(*HanleParam, int), param *HanleParam,
) error {
	goPool := make(chan struct{}, maxGoNum) // 限制同时最多开启 maxGoNum 个协程
	signal := make(chan struct{})           // 通知请求完成
	defer close(goPool)
	defer close(signal)

	go func() {
		defer handlePanic()()
		for i := 0; i < param.Num; i++ {
			// 每个数据创建协程处理时向chanel中写数据,超过限制的协程序数量时,阻塞
			goPool <- struct{}{}

			go func(param *HanleParam, index int) {
				defer handlePanic()()
				// 处理数据
				handle(param, index)
				// 协程处理完毕,释放限制
				<-goPool
				// 处理完成通知
				signal <- struct{}{}
			}(param, i)
		}
	}()
	
	// 定时器
	if timeout <= 0 {
		timeout = 0x7FFFFFFF * time.Second
	}
	doTmer := time.After(timeout)
	// 数据处理通知,统计数量达成所有数据,则跳出循环
	for i := param.Num; i > 0; i-- {
		select {
		case <-signal:
		case <-doTmer:
			return fmt.Errorf("run timeout")
		}
	}
	return nil
}


func handlePanic() func() {
	return func() {
		if r := recover(); r != nil {
			return
		}
	}
}

调用该并发接口

func main() {
	data := []int{1, 2, 3, 4, 5}

	fmt.Println("=====")
	err := GoHandle(2, 10*time.Second,
		handle, &HanleParam{Data: data, Num: len(data), Mx: new(sync.Mutex)})
	if err != nil {
		fmt.Println("gohandle: ", err)
	}
	fmt.Println("=====...")
}

func handle(param *HanleParam, index int) {
	data, ok := param.Data.([]int)
	if !ok {
		return
	}
	time.Sleep(2 * time.Second)

	// 此处处理数据时,可加锁
	param.Mx.Lock()
	fmt.Printf("goroutine[%d]: %d\n", index, data[index])
	param.Mx.Unlock()
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值