【go语言】

文章介绍了一种仅使用Go语言的channel来创建协程池的方法,通过创建一个固定容量的channel来管理worker,每个worker在完成任务后会返回到channel中等待新的任务。这种方式可以实现协程的复用,提高并发处理的效率。在main函数中,创建了一个协程池并执行了大量任务,然后关闭通道结束工作。
摘要由CSDN通过智能技术生成

只用channel就可以实现高效简洁的协程池

只使用channel,而不用go的waitgroup等其他元素,就可以实现协程复用,并且高效简洁,废话不多说直接show your code!

package main

import (
	"fmt"
	"time"
)

type WorkerPool struct {
	maxCapacity   int
	workerChannel chan chan func()
	closeChannel  chan func()
}

func NewWorkerPool(capacity int) *WorkerPool {
	return &WorkerPool{
		maxCapacity:   capacity,
		workerChannel: make(chan chan func(), capacity),
		closeChannel:  make(chan func()),
	}
}

func (wp *WorkerPool) Start() {
	for i := 0; i < wp.maxCapacity; i++ {
		go wp.startWorker()
	}
}

func (wp *WorkerPool) startWorker() {
	worker := make(chan func())
	wp.workerChannel <- worker

	for {
		select {
		case task := <-worker:
			task()                     // 执行任务
			wp.workerChannel <- worker // 将协程重新放回可用协程通道
		case <-wp.closeChannel: // 接收任务通道的关闭信号
			return
		}
	}
}

func (wp *WorkerPool) Execute(task func()) {
	worker := <-wp.workerChannel // 从可用协程通道获取一个协程
	worker <- task               // 将任务发送给协程执行
}

func main() {
	pool := NewWorkerPool(5) // 创建一个最大容量为5的协程池
	pool.Start()

	now := time.Now()
	for i := 0; i < 10000; i++ {
		taskID := i
		pool.Execute(func() {
			fmt.Printf("Task %d completed\n", taskID)
		})
	}

	close(pool.closeChannel) // 关闭任务通道,通知协程池停止接收新任务
	//fmt.Println("Num:", runtime.NumGoroutine())
	fmt.Println("cost_time:", time.Since(now))
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值