随笔之如何实现一个线程池
一 缘由:
2 支持超时任务。比如提交一个Task,可以设置5秒后执行,并且可以设置执行一次,还是每隔5秒执行。
二 Windows平台
1 Windows平台实现一个线程池(不使用完成端口),我最初的想法是:
>创建比如20个线程,然后这20个线程都WaitForXXXObject,在一个Event上。
>添加任务的时候,触发这个Event,为了避免惊群现象(例如只有1个任务的时候,20个线程全起来抢任务,结果其他19个线程白起来了。这样导致系统效率会显著下降。),CreateEvent的时候可以设置下,保证只有一个在等待的线程会启动。
2 Windows平台上使用完成端口
>使用完成端口就简单了,线程池中的线程个数将是CPU个数的2倍(这个是推荐值,应该也是绝大多数人的选择了)。
>Wait的时候,当有事情发生时,内核会自动调度一个线程去执行。而且接连的任务会倾向于使用同一个线程来执行。这样可以减少线程切换的时间。所以,惊群效应由内核保证不会发生了。
>解决超时任务的检查,这个也没有更好的办法。只能采取和上面一样的方法了。
三 Linux平台
1 Linux平台实现线程池
四 一个实际的线程池设计
>对用户来说,线程池处理的是任务。所以给线程池添加的应该是任务。那么任务有高,中,低三个优先级。另外,有些任务是需要一直占有线程的,所以还区分persist和非persist两种。设计的时候,分别有高中低三个优先级队列。线程池在挑选任务的时候,先处理高,然后是中低优先级的任务。
>当线程池中的线程个数小于任务个数的时候,线程池应该自动增加池中的线程。这个就是自动扩展。当线程池中的线程检测到自己长时间没有工作,并且池中线程数量超过最大设置的数量时候,那么线程应该自动退出。按这种方式就可以实现一个比较好的自动缩减。这样的话,每个线程都需要有一个超时检测,看看自己是不是多余了。
>对于定/超时任务,需要给线程池增加一个高优先级,persist的job。这个job自带一个定时任务队列。添加定时任务,其实就是给这个队列添加成员。然后唤醒该线程。这个线程从其中选择一个任务,然后再提交给线程池。(其实就是我们在Windows上的方案)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?