算法编程题-golang语言协程池

embedded/2024/11/20 3:50:01/

算法编程题-golang语言协程池

      • 协程池
      • 代码实现

实现线程池或者协程池是面试经常需要手写的题型。本文将介绍协程池如何实现。

协程池

池化技术是很重要的一种思想,将一些频繁使用但是创建开销比较大的对象自定义保存起来,反复使用,典型的有线程池、内存池、mysql连接池等等。协程是用户级别更加轻量化的线程,使用协程池来维护一个永远工作不回收的协程池也可以优化业务逻辑的效率。
笔者的协程在思路上借鉴了一些Java线程池七大参数的思想,分为核心协程和非核心协程,初始时只有核心协程工作,如果工作数量比较多还会起一些非核心协程来工作,但是这些非核心协程如果长时间没有工作也会被销毁,这其中涉及到的工作数量比较多的阈值、非核心协程多少时间不工作会被销毁都是可以由用户调整的参数。工作其实就是函数的抽象,本文的协程池通过对于信道的封装定义了一个future对象,用来保存一个任务的运行结果。协程池在启动后,会写一个协程daemon,用来监测协程池的状态,决定是否要起非核心协程。此外,还实现了一个优雅关闭协程池的功能,保证所有协程在完成自己手上的工作后立即退出,然后主程序里面将所有的信道关闭。任务的分发则是通过原生的信道来实现的。
不可否认,这里实现的这个协程池只是一个demo,后续可以参考golang优秀的第三方协程池库进行相应的优化。

代码实现

代码实现如下:

type Future struct {ch chan interface{}
}func (f *Future) Get() interface{} {var res interface{}res, ok := <- f.chfor !ok {time.Sleep(1 * time.Millisecond)res, ok = <- f.ch}return res
}type Work struct {work func(args []interface{}) interface{}args []interface{}res  *Future
}type Worker struct {taskChannel chan WorkisCore      boolquit        chan struct{}keepAliveTime  time.Durationwg *sync.WaitGroup
}func NewWorker(taskChannle chan Work, isCore bool, quit chan struct{}, keepAliveTime time.Duration, wg *sync.WaitGroup) *Worker {return &Worker{taskChannel: taskChannle, isCore: isCore, quit: quit, keepAliveTime: keepAliveTime, wg: wg}
}func (w *Worker) Work() {defer w.wg.Done()timer := time.NewTimer(w.keepAliveTime)for {select {case <- timer.C:if !w.isCore {return}case <- w.quit: returncase task := <- w.taskChannel:res := task.work(task.args)task.res.ch <- restimer.Reset(w.keepAliveTime)continue}}
}type ThreadPool struct {workers  []*WorkercoreThreads intmaxThreads intkeepAliveTime time.DurationtaskChannel chan Workquit chan struct{}threshold intdiscount intwg *sync.WaitGroup
}func NewThreadPool(coreThreads, maxThreads int, keepAliveTime time.Duration, threshold, discount int) *ThreadPool {taskChannel := make(chan Work, maxThreads * 2 + 1)quit := make(chan struct{}, maxThreads)workers := make([]*Worker, 0)var wg sync.WaitGroupfor i := 0; i < coreThreads; i++ {worker := NewWorker(taskChannel, true, quit, keepAliveTime, &wg)go worker.Work()workers = append(workers, worker)wg.Add(1)}t := &ThreadPool{workers: workers, coreThreads: coreThreads, maxThreads: maxThreads, keepAliveTime: keepAliveTime, taskChannel: taskChannel, quit: quit, threshold: threshold, discount: discount, wg: &wg}go t.daemon()return t
}// Submit 往协程池中提交任务
func (t *ThreadPool) Submit(function func(args []interface{}) interface{}, args []interface{}) *Future {resChannel := make(chan interface{}, 1)future := &Future{ch: resChannel}work := Work{work: function, args: args, res: future}t.taskChannel <- workreturn future
}// 线程池后台监控程序
func (t *ThreadPool) daemon() {if len(t.taskChannel) > t.threshold {// 准备在起的协程数threadNum := min(t.maxThreads - len(t.workers), len(t.taskChannel) / t.discount)for i := 0; i < threadNum; i++ {worker := NewWorker(t.taskChannel, false, t.quit, t.keepAliveTime, t.wg)go worker.Work()t.workers = append(t.workers, worker)t.wg.Add(1)}}
}// Close 优雅关闭协程池
func (t *ThreadPool) Close() {for i := 0; i < t.maxThreads; i++ {t.quit <- struct{}{}}t.wg.Wait()close(t.quit)close(t.taskChannel)
}

一个简单的单元测试例子:

func TestThreadPool(t *testing.T) {tp := NewThreadPool(2, 5, 2 * time.Second, 8, 4)args := []interface{}{3, 4}for i := 0; i < 10; i++ {tp.Submit(func(args []interface{}) interface{} {a := args[0].(int)b := args[1].(int)c := a + btime.Sleep(5 * time.Second)return c}, args)}f := tp.Submit(func(args []interface{}) interface{} {a := args[0].(int)b := args[1].(int)c := a + btime.Sleep(5 * time.Second)return c}, args)res := f.Get()t.Logf("get 4+3=%d", res.(int))tp.Close()
}

http://www.ppmy.cn/embedded/138958.html

相关文章

unity小:shaderGraph不规则涟漪、波纹效果

实现概述 在本项目中&#xff0c;我们通过结合 Sine、Polar Coordinates 和 Time 节点&#xff0c;实现了动态波纹效果。以下是实现细节&#xff1a; 核心实现 Sine 波形生成&#xff1a; 使用 Sine 节点生成基本的波形。该节点能够创建周期性变化&#xff0c;为波纹效果提供…

不同规模的企业需要部署哪种组网?

针对不同规模的企业&#xff0c;合理的企业组网方式可以帮助优化网络性能和管理效率。以下是适合各类企业的组网建议。 一、小型企业&#xff08;少于50用户&#xff09; 选择经济实用的网络设备 小型企业可选择简单、成本合理的网络设备&#xff0c;如家庭路由器或小型商用路由…

前端学习八股资料CSS(三)

更多详情&#xff1a;爱米的前端小笔记&#xff0c;更多前端内容&#xff0c;等你来看&#xff01;这些都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们的支持才是我不断更新的动力&#xff01;找…

使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法

在使用uniapp开发微信小程序时候&#xff0c;过多的引入uni_modules的组件库&#xff0c;会导致主包文件过大&#xff0c;导致无法上传微信小程序&#xff0c;主包要求大小不超过1.5MB.分包大小每个不能超过2M。 解决方法&#xff1a;分包。 1.对每个除了主页面navbar的页面进…

解决在使用JetBrains IDEs(如PyCharm或CLion)进行GitHub项目分享时,用户经常遇到“此站点的访问已被限制”的问题

解决在使用JetBrains IDEs&#xff08;如PyCharm或CLion&#xff09;进行GitHub项目分享时&#xff0c;用户经常遇到“此站点的访问已被限制”的问题 在使用JetBrains IDEs&#xff08;如PyCharm或CLion&#xff09;进行GitHub项目分享时&#xff0c;用户经常遇到“此站点的访…

IT行业现状与未来趋势

IT行业现状与未来趋势 在这个快速变化的世界里&#xff0c;IT行业的风向标总是引人注目。就像海面上的潮汐&#xff0c;科技带来的变化时常令人惊叹。你是否曾想过&#xff0c;这些变化背后隐藏着怎样的力量&#xff1f;让我们一起探讨当前IT行业的现状与未来趋势&#xff0c;…

计算机视觉:赋予机器“看”的能力

引言 计算机视觉是一门科学&#xff0c;它试图使计算机能够像人类一样解释和理解视觉信息。这个领域结合了人工智能、机器学习、计算机科学和认知心理学等多个学科的知识&#xff0c;旨在创建能够“看”和“理解”图像和视频的系统。随着技术的进步&#xff0c;计算机视觉已经…

Python+7z.exe实现自动化压缩与解压

简介 我们将使用subprocess模块来调用系统命令行工具7z.exe&#xff0c;实现文件的自动压缩与解压。 环境准备 在开始之前&#xff0c;请确保您的计算机上安装了7z.exe工具。7z.exe是7-Zip程序的一部分&#xff0c;可以从7-Zip官方网站下载。安装完成后&#xff0c;请确保7z.e…