Windows下一个比较完美的线程池实现(更新)

Java实现系统目录实时监听更新。 SDK1.7新增的nio WatchService能完美解决这个问题。美中不足是如果部署在window系统下会出现莫名其妙的文件夹占用异常导致子目录监听失效,linux下则完美运行。这个问题着实让人头疼。如果有童鞋找到问题根源请一起探讨。   这里简单的列出用Servlet实现的基本类供大家参考。首先是核心的实现类。    package com.event; import static j 阅读详情

1.  前言

线程池不是一个新鲜的东西,网上能找到很多原理、实现,甚至很多库都提供了实现,比如微软的 ATL::CThreadPool, Vista后提供的CreateThreadpoolWork, boost 中提供的 thread_pool, 优快云、CodeProject 等网站上很多人已经实现的类。但这些库往往只支持启动任务,而不能很好地停止任务(相信很多人都会和我一样有这个需求),于是我在FTL中写了一个个人认为还比较完美的线程池。

2.  功能

线程池已经进行了更新(下载地址为: http://download.youkuaiyun.com/detail/fishjam/9409236 )


本线程池提供了如下功能:

1.       能根据任务个数和当前线程的多少在最小/最大线程个数之间自动调整(Vista后的系统有 SetThreadpoolThreadMaximum 等函数有类似功能),现已支持动态改变最小、最大值;

2.      能方便的对任一任务进行取消操作,无论该任务是等待运行状态还是正在运行状态都支持(相比较而言,WaitForThreadpoolWorkCallbacks 函数只能取消尚未运行的任务);

3.      能对单个Job或整个线程池进行 暂停、继续、停止 处理 -- 需要 JobBase 的子类根据 GetJobWaitType 的返回值进行处理,能对整个线程池进行安全的暂停、继续、停止处理 。

4.      支持回调方式的反馈通知

5.      使用模版方式实现,能方便的进行参数传递

6.      在加入任务时可以设置优先级(目前尚不支持动态调整) ,现已支持动态调整优先级

7.      使用的是微软的基本API,能支持WinXP、Vista、Win7等各种操作系统(CreateThreadpoolWork 等只能在Vista后才能使用)

8.      可以设置等待Job的最大个数,并在加入Job时,队列满了的话,可以设置等待超时并根据返回值进一步处理

3.  UML图示和简单说明

其UML图比较简单,主要的只有三个类:

CFThreadPool – 线程池的管理类,负责整个线程池的管理工作,直接使用即可。

CFJobBase – Job的基类,如果想实现自己的Job,必须从这个类继承,并实现其中的Run/ OnCancelJob 等函数。

IFThreadPoolCallBack– 可选的回调实现,可以通知调用段 Job 的启动、停止、取消、进度通知、错误等各种状态的改变。

4.  实现说明

以下部分简单介绍了一些比较重要的代码实现,具体请参见示例代码和其中的注释部分。

4.1.     Job容器

本线程池类中有两种Job的容器,分别是等待运行的Jobs和当前正在运行的Jobs。因为有不同的需求,其定义分别如下(两种容器类型的选择,其理由已经写得比较详细,大家自行分析即可)

     //! 保存等待Job的信息,由于有优先级的问题,而且从最前面开始取任务,因此保存成set

//! 保证优先级高、JobIndex小(同优先级时FIFO) 的Job在最前面

     typedeftypenameUnreferenceLess<CFJobBase<T>* >JobBaseUnreferenceLess;

     typedefstd::set<CFJobBase<T>*,JobBaseUnreferenceLess > WaitingJobContainer;

     WaitingJobContainer        m_WaitingJobs;    //!等待运行的Job

 

     //! 保存运行Job的信息,由于会频繁加入、删除,且需要按照JobIndex查找删除,因此保存成map

     typedefstd::map<LONG,CFJobBase<T>* >   DoingJobContainer;

     DoingJobContainer      m_DoingJobs;  //! 正在运行的Job

 

4.2.     Job优先级

代码中通过operator < 方法比较CFJobBase<T>::m_nJobPriority和 JobIndex,在SubmitJob时保证其在 set 中的顺序来保证 优先级高的Job先执行,相同优先级的Job采用FIFO方式。

4.3.     Job对暂停、停止的支持

为了支持暂停、停止,Job的子类必须在工作循环中调用父类提供 GetJobWaitType方法,并判断其返回值。如果返回值为ftwtStop 表示用户请求了停止,需要进行必要的清除工作。GetJobWaitType的实现请参见代码(本质是等待m_hEventJobStop, m_pThreadPool->m_hEventStop, m_pThreadPool->m_hEventContinue这三个手动重置事件之一)

4.4.     线程池对Job的控制

线程池中主要有以下的一些函数,因为意义根据名字很容易猜出,就不再详细介绍,详见示例。

Start(LONGnMinNumThreads, LONG nMaxNumThreads);

StopAndWait(DWORDdwTimeOut = FTL_MAX_THREAD_DEADLINE_CHECK);

ClearUndoWork();

SubmitJob(CFJobBase<T>*pJob, LONG* pOutJobIndex); //加入Job,会返回Job在Pool中的唯一索引,可以通过CancelJob 取消。

Pause/Resume/Stop// 对整个线程池请求暂停、继续、停止的操作。注意:需要Job子类的配合才能达成目标。

4.5.     资源的处理

CFJobBase子类需要 Initialize、Run、Finalize、OnCancelJob 这几个虚函数。

当Job运行的时候,其逻辑为 if(Initialize){ Run -> Finalize; },需要在 Finalize 中释放资源;

当Job没有运行的时候就被取消或Pool停止,则会调用 OnCancelJob,需要在其中释放资源。

5.  示例程序

编写了简单的MFC示例程序,其界面如图所示:

因为UI不是重点,而且本人也比较懒,所以没有弄很好的UI出来,所有的运行信息请参见VisualStudio中的“输出”窗口。

Start 按钮启动线程池,示例中设置的最小、最大线程个数是 2-4(即会根据加入的Job自动在 2-4 个线程之间自动调整)。

       三个AddJob按钮分别是增加 高、普通、低优先级的Job,加入后可以在日志中查看其运行的顺序。

       两个CancelJob按钮分别是从前面、后面的JobIndex取消Job(实际上支持任和有效的JobIndex)。

      注意:新界面

      

6.  特别说明

6.1.     IFThreadPoolCallBack 回调的同步

Pool 调用 IFThreadPoolCallBack 接口的各个方法时,为了性能上的考虑,没有加锁进行同步。使用时如果有需要,最好自行同步。

6.2.     单任务的暂停、继续 VS Pool的暂停、继续

在开发过程中,考虑过是提供单任务的暂停、继续 还是 整个Pool 的暂停、继续,考虑到目前的需求,暂时只支持整个Pool的暂停,免得过分复杂,如有需要,大家可以自行参考CancelJob实现。

6.3.     可能存在的Bug和解决方法

在开发的过程中,对各个部分都进行了详细的分析、考虑和测试,应该没有较大的Bug。目前只想到一种在极端情况下,可能会造成的Bug,特提出以免各位踩雷。

描述:因为是多线程的代码,所以在极端情况下,可能出现SubmitJob函数尚未返回,对应的Job就执行完毕(或 Initialize失败直接返回)的情况。此时如果调用端采用了将 *pOutJobIndex保存起来,在 OnJobEnd 中清除的逻辑,可能会因为 OnJobEnd 找不到对应的JobIndex 而出现逻辑错误。

解决方法:在调用 SubmitJob 的代码和OnJobEnd 的回调代码中,使用相同的锁机制保证即可(这个也应该由调用者来保证微笑)。


源码和示例程序的下载地址请参见本人的资源列表(可能需要等一段优快云刷新的时间)。

新的下载地址:  http://download.youkuaiyun.com/detail/fishjam/9409236

旧的下载地址:  http://download.youkuaiyun.com/detail/fishjam/5106672

C#计时器深度解析:从UI更新到后台服务的实战指南 在C#开发中,计时器是实现定时任务的核心组件,其原理基于操作系统级别的计时机制,通过封装系统API为开发者提供便捷的定时功能。计时器的技术价值在于能够高效管理周期性或延迟性任务,是构建响应式应用和自动化后台服务的关键工具。在应用场景上,计时器广泛用于UI动画更新、数据轮询、后台作业调度以及实现重试机制等。本文聚焦于.NET中的三种主要计时器:System.Windows.Forms.Timer适用于UI线程安全的界面更新,System.Timers.Timer专为服务器端多线程任务设计,而System.Th 阅读详情

相关推荐

C++11单头文件线程池:原理、实现与生产环境实战指南

并发编程是现代软件开发的核心技术之一,旨在通过多线程并行执行任务来提升程序性能。其基本原理是创建多个执行流,共享进程资源,以充分利用多核CPU的计算能力。线程池作为并发编程的关键技术,通过预先创建并管理一组工作线程,避免了线程频繁创建与销毁的巨大开销,同时提供了统一的任务队列和调度机制,极大地简化了并发控制,减少了死锁和数据竞争的风险。这项技术的核心价值在于提升系统吞吐量、降低资源消耗并增强程序稳定性,广泛应用于服务器后端、数据处理、高并发网络服务等场景。本文聚焦于C++11标准库实现的单头文件线程池,深入

weixin_30540691的博客 380

MFC线程的使用

一、创建线程       线程内核对象就是一个包含了线程状态信息的数据结构。每次对CreateThread 的成功调用,系统都会在内部为其分配一个内核对象。创建线程方法: HANDLE WINAPI CreateThread(   LPSECURITY_ATTRIBUTES lpThreadAttributes,       // 线程安全属性   SIZE_T dwStac...

只为龙舞的博客 2498

C++多线程编程实战:从std::thread到线程池的完整指南

并发编程是现代软件开发的核心概念,它允许程序同时执行多个任务,从而充分利用多核处理器资源,提升系统吞吐量和响应速度。其基本原理是通过创建多个执行流(线程)来并行处理任务,这些线程共享进程的内存空间,但拥有独立的执行栈。在C++中,多线程技术价值显著,能够解决I/O阻塞、计算密集型任务并行化以及高并发服务器等场景下的性能瓶颈。应用场景广泛,包括网络服务器、图形界面程序、数据处理和科学计算等领域。本文聚焦于C++多线程编程的实战方法,系统梳理了从标准库的std::thread、平台特定的pthread和Crea

weixin_34221276的博客 579

mfc 实现的线程池

在MFC下实现的简单线程池。主要用来处理比较频繁的但又耗时比较短的任务。通过预先创建好的线程能够最快的处理任务,而不会将大量的时间用在创建线程和销毁线程。 具体使用方法为创建线程池对象,派生一个任务子类,具体只需要关心任务类的run函数和任务数据 下载MFC线程池源码:ThreadPoolTest.rar 具体实现代码如下: //-------------header fi

Mtour's blog 7351

MFC实现线程池(附完整源码)

MFC实现线程池(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 659

MFC 线程池

自己做的简单的线程池 在vc6下实现 个站: www.gddhx.com

Windows线程池

文章来源:http://www.cnblogs.com/coser/archive/2012/03/10/2389264.html 什么是线程池? 诸如web服务器、数据库服务器、文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务。构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就创建一个新的服务对象,然后在新的服务对象中为请求服务。但当有大

$firecat利白的代码足迹$ 1928

线程并发线程池

该工程是在vs2008下建的mfc工程,服务器程序,采用线程并发,线程池,线程同步技术,允许5个客户端同时访问,已编译通过。提供客户端执行文件。

C#线程池底层原理与生产调优实战

线程池是.NET中实现高并发任务调度的核心基础设施,其本质是基于Windows内核线程池的对象池化机制,通过预分配、复用和智能回收线程资源,解决创建销毁开销大与CPU/内存资源有限之间的矛盾。它并非简单的异步执行容器,而是融合了任务队列管理、执行上下文传递、I/O完成端口协同等操作系统级能力的资源代理。在实际应用中,ThreadPool直接影响API响应延迟、GC压力与突发流量承载能力,尤其在微服务、实时风控、金融行情等低延迟场景中,合理配置MinThreads、理解QueueUserWorkItem的内存

xiang_fu的博客 644

学生管理网络MFC版采用线程池 连接池TCP协议

采用线程池 连接池 数据库 采用mysql,listcontr控件 右键菜单 此程序仅供学习 功能 增删改查学生,基本上各种非法操作验证都加了

【经验分享】使用Keil5烧录代码遇到的问题及解决方法

本文介绍了在使用Keil5烧录代码过程中可能遇到的常见问题,主要为编译错误和下载失败,并提供了解决方案和注意事项。通过本文中提供的具体解决方案和注意事项,希望能够帮助读者更加顺利地进行Keil5烧录代码操作,提高开发效率和成果实现。

qq_63195670的博客 1万+

C++异步编程入门:从std::future到线程池的极简实现

异步编程是现代软件开发中提升系统响应能力和资源利用率的核心技术,其基本原理是将耗时的任务交给后台线程执行,主线程继续处理其他事务,通过回调或future机制获取结果。这种模式在I/O密集型和高并发场景中尤为重要,能有效避免阻塞,提升吞吐量。C++11标准库为此提供了std::async、std::future和std::promise等基础组件,它们构成了异步任务提交与结果获取的基石。本文通过一个极简的异步模型,手把手演示如何利用std::thread和std::future实现最基本的异步执行流程,并深入

weixin_34327761的博客 341

Gemini Enterprise免费试用攻略:解锁企业级AI平台的隐藏技巧与避坑指南

本文详细介绍了Gemini Enterprise免费试用的全流程攻略,包括注册优化、团队协作、资源管理和典型应用场景。通过解锁企业级AI平台的核心功能如Gemini 3.0 Pro模型和Nano Banana图像生成系统,帮助企业高效评估AI与业务的契合度。文章还提供了安全合规与数据管理的实用建议,确保试用过程顺畅无忧。

weixin_29233857的博客 657

C++11工程级应用:从智能指针到线程池的现代C++实战指南

在C++编程中,内存管理和并发编程是两大核心挑战,直接关系到程序的性能、稳定性和安全性。传统手动管理内存和平台相关的多线程开发方式,不仅容易引入内存泄漏、数据竞争等难以调试的Bug,也极大地增加了跨平台开发的复杂性。C++11标准通过引入智能指针和标准线程库,从语言层面提供了系统性的解决方案。智能指针(如std::unique_ptr、std::shared_ptr)基于RAII(资源获取即初始化)思想,实现了资源的自动生命周期管理,有效防止内存泄漏。标准线程库(如std::thread、std::mute

weixin_30530939的博客 471

告别兼容性困扰:在F-Droid中安全部署Termux的完整指南

本文提供了一份在F-Droid中安全部署Termux的完整指南,旨在彻底解决Android设备上的兼容性困扰。文章详细阐述了为何选择F-Droid而非Google Play商店,并逐步指导用户完成从彻底清理旧版本、安装F-Droid客户端、授予权限到最终安装配置Termux的全过程。指南还涵盖了进阶的稳定性配置、数据迁移方法以及常见问题排查,确保用户获得一个稳定、无冲突的命令行工作环境。

weixin_29224309的博客 944

NoUnityCN:绕过地域限制,从Unity官方CDN直链下载全版本编辑器

在软件开发和游戏制作领域,内容分发网络(CDN)是保障全球用户高速、稳定获取大型文件的核心基础设施。其原理是通过将资源缓存至遍布各地的边缘节点,使用户能从地理距离最近的服务器获取数据,从而显著提升下载速度并降低源站压力。这一技术对于需要频繁下载大型开发工具(如游戏引擎)的团队而言,价值在于能确保开发环境部署的一致性与效率,是构建自动化CI/CD流水线和团队协作的基础。然而,当开发者因网络策略或地域限制无法直接访问官方CDN时,获取安装文件便成为阻碍工作流的痛点。NoUnityCN项目正是针对此场景的工程实践

weixin_33473110的博客 312

手写C++11线程池:从零实现生产级并发基座

线程池是现代C++并发编程的核心基础设施,其本质是基于生产者-消费者模型的资源受控任务调度机制。依托C++11标准提供的std::thread、std::mutex、std::condition_variable和std::packaged_task等原语,可构建线程安全、异常可传播、内存有界的轻量级实现。技术价值在于消除线程频繁创建销毁开销、防止OOM与死锁、保障异常隔离与结果可获取,广泛应用于图像处理、日志分析、API聚合等IO/CPU混合型场景。本文聚焦C++11原生能力落地,详解有界队列设计、移动语

diaoju3333的博客 297

STM32G474多通道ADC电压采集:软件触发与单次转换实战

本文详细介绍了STM32G474多通道ADC电压采集的实战方法,重点讲解了软件触发与单次转换的实现技巧。通过硬件设计、HAL库配置、多通道轮询采集及数据处理等环节的详细解析,帮助开发者高效完成精确电压采集任务。文章还提供了常见问题调试技巧和性能优化建议,适用于需要高精度电压监测的嵌入式应用场景。

weixin_28720767的博客 462

C++多线程TCP服务器实战:线程池与非阻塞监听模型详解

网络编程是构建高性能分布式系统的基石,其核心在于理解Socket通信、TCP协议与并发处理机制。通过多线程技术,服务器能够同时处理多个客户端连接,而线程池模型则有效解决了频繁创建销毁线程带来的性能开销问题,实现了资源的可控复用。这种架构在游戏服务器、即时通讯后台等高并发场景中具有重要技术价值。本文以C++11/17现代特性为基础,深入解析了线程池的实现细节与非阻塞监听的设计思路,并提供了从Socket API调用到资源管理的完整实战代码,帮助开发者跨越从Demo到工程实践的鸿沟。

weixin_33924312的博客 435

智能循迹小车之PID控制算法

从光电传感器获取信号确认小车和黑线的偏离角度,通过PID算法算出左右车轮速度,控制小车前进或者后退。

yzj199921的博客 4639

基于STM32的智能电子秤设计毕业论文

摘要:本文设计了一款基于STM32F103C8T6的智能电子秤系统,通过HX711称重传感器实现高精度测量,采用OLED显示和矩阵键盘完成人机交互。系统包含重量采集、数据处理、单价设置、去皮清零及总价计算等功能模块,经测试测量误差小于0.1%,稳定性良好。研究实现了低成本、高可靠性的智能称重方案,为后续无线传输和AI算法集成奠定了基础。关键词:STM32;智能电子秤;HX711;OLED显示;矩阵键盘。

3254968421的博客 848

C++实现RDP屏幕更新核心:从捕获、差异检测到网络传输的工程实践

远程桌面协议(RDP)的核心在于高效的屏幕更新机制,它涉及实时捕获桌面变化、编码压缩并通过网络传输。其技术原理基于差异检测与增量更新,通过比较前后帧的变化区域,仅传输“脏矩形”,并结合自适应压缩策略(如JPEG、LZ4)在画质与带宽间取得平衡。这项技术的价值在于实现低延迟、高流畅性的远程交互体验,广泛应用于远程办公、IT运维和云桌面等场景。本文以C++工程实践为例,深入探讨了如何利用DirectX捕获、自定义协议设计及Boost.Asio网络库,构建一个高性能的RDP-like屏幕更新系统,其中涉及Dire

weixin_33834910的博客 369

华为OD机试双机位C卷-热点网站统计 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 热点网站统计,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。 华为od机考真题 - 热点网站统计。

qq_45776114的博客 779

Windows 11 Build 25182深度解析:从UI革新到内核优化的技术演进

操作系统更新不仅是功能迭代,更是底层架构现代化的体现。其原理在于通过渐进式重构,将传统组件迁移至现代框架,以提升性能、安全性和开发效率。这一过程的技术价值在于统一用户体验、优化资源管理并为AI集成铺平道路。典型的应用场景包括系统工具现代化、设置应用整合以及输入体验的微调。以Windows 11 Build 25182为例,本次更新在任务管理器等系统组件中深化了WinUI 3与XAML Islands的应用,持续推进控制面板功能的迁移,并对.NET运行时及内核进行了静默优化。这些改动共同指向微软生态向现代化应

aodiyi6351的博客 396

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

现代C++并发编程实战:从多线程到线程池的完整指南

并发编程是现代软件开发的核心技术,它通过允许多个任务同时执行来提升程序性能和资源利用率。其基本原理涉及任务调度与同步机制,旨在解决多核处理器环境下的性能瓶颈问题。在技术价值层面,并发编程能够显著提升高并发网络服务器、实时图形界面及大数据处理等应用的吞吐量和响应速度。C++作为高性能系统开发的主要语言,自C++11起提供了标准化的并发支持,包括线程、互斥锁、原子操作等关键组件。本文聚焦于C++并发编程的实战应用,深入解析数据竞争、死锁等常见问题的解决方案,并演示如何构建高效的线程池来处理并发任务。通过理解st

djai0102的博客 390

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: DebugInfoFIlter -- DirectShow调试工具
下一篇: 在Exe和Dll之间共享变量
fishjam
博客等级 码龄23年 170粉丝 37原创
评论 28
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值