线程池完整实例代码 MFC

时间: 2023-10-17 18:07:25 浏览: 47
以下是一个基于 MFC 的线程池完整实例代码: 首先,定义一个任务类 CTask,它包含一个虚函数 Run,用于执行具体的任务。这个虚函数需要在派生类中实现。 ```c++ class CTask { public: virtual void Run() = 0; }; ``` 然后,定义一个线程池类 CThreadPool,它包含一个任务队列和一组工作线程。线程池的主要作用是将任务添加到任务队列中,并从队列中取出任务分配给工作线程执行。 ```c++ class CThreadPool { public: CThreadPool(int nMaxThreads = 4); virtual ~CThreadPool(); void AddTask(CTask* pTask); protected: static UINT WINAPI WorkerThread(LPVOID lpParam); void CreateThreads(); CTask* GetTask(); CRITICAL_SECTION m_cs; HANDLE m_hSemaphore; std::queue<CTask*> m_TaskQueue; std::vector<HANDLE> m_vecThreadHandles; bool m_bStop; int m_nMaxThreads; }; ``` 在线程池类的构造函数中,我们初始化了信号量和临界区,并创建了指定数量的工作线程。在 AddTask 函数中,我们将任务添加到任务队列中,执行过程中需要加锁保证线程安全。在 GetTask 函数中,我们从任务队列中取出一个任务,如果队列为空,就等待信号量。在 WorkerThread 函数中,每个工作线程都会不断地从任务队列中取出任务执行。 ```c++ CThreadPool::CThreadPool(int nMaxThreads) : m_hSemaphore(NULL), m_bStop(false), m_nMaxThreads(nMaxThreads) { InitializeCriticalSection(&m_cs); m_hSemaphore = CreateSemaphore(NULL, 0, LONG_MAX, NULL); CreateThreads(); } CThreadPool::~CThreadPool() { m_bStop = true; ReleaseSemaphore(m_hSemaphore, m_nMaxThreads, NULL); WaitForMultipleObjects(m_vecThreadHandles.size(), &m_vecThreadHandles[0], TRUE, INFINITE); for (std::vector<HANDLE>::iterator it = m_vecThreadHandles.begin(); it != m_vecThreadHandles.end(); ++it) { CloseHandle(*it); } CloseHandle(m_hSemaphore); DeleteCriticalSection(&m_cs); } void CThreadPool::AddTask(CTask* pTask) { EnterCriticalSection(&m_cs); m_TaskQueue.push(pTask); ReleaseSemaphore(m_hSemaphore, 1, NULL); LeaveCriticalSection(&m_cs); } void CThreadPool::CreateThreads() { for (int i = 0; i < m_nMaxThreads; ++i) { HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, WorkerThread, this, 0, NULL); m_vecThreadHandles.push_back(hThread); } } CTask* CThreadPool::GetTask() { CTask* pTask = NULL; EnterCriticalSection(&m_cs); if (!m_TaskQueue.empty()) { pTask = m_TaskQueue.front(); m_TaskQueue.pop(); } LeaveCriticalSection(&m_cs); return pTask; } UINT WINAPI CThreadPool::WorkerThread(LPVOID lpParam) { CThreadPool* pThreadPool = (CThreadPool*)lpParam; while (!pThreadPool->m_bStop) { CTask* pTask = pThreadPool->GetTask(); if (pTask != NULL) { pTask->Run(); delete pTask; } else { WaitForSingleObject(pThreadPool->m_hSemaphore, INFINITE); } } return 0; } ``` 最后,我们来看一下如何使用线程池。首先创建一个派生自 CTask 的任务类,实现 Run 函数。然后创建一个线程池对象,并向其中添加任务。任务会被自动分配给工作线程执行。 ```c++ class CMyTask : public CTask { public: virtual void Run() { // do some work } }; int main() { CThreadPool threadPool; for (int i = 0; i < 10; ++i) { CMyTask* pTask = new CMyTask(); threadPool.AddTask(pTask); } return 0; } ```

相关推荐

最新推荐

recommend-type

Java 线程池ExecutorService详解及实例代码

主要介绍了Java 线程池ExecutorService详解及实例代码的相关资料,线程池减少在创建和销毁线程上所花的时间以及系统资源的开销.如果不使用线程池,有可能造成系统创建大量线程而导致消耗系统内存以及”过度切换
recommend-type

java简单实现多线程及线程池实例详解

主要为大家详细介绍了java简单实现多线程,及java爬虫使用线程池实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

NetDxf 编程 实例命令代码.docx

整理和索引的NetDxf的各种图形绘制,图层,样式,尺寸标注,块命令等的设置实例代码,共152个实例,200页代码,满足C# 的DXF 操作。
recommend-type

springmvc配置线程池Executor做多线程并发操作的代码实例

今天小编就为大家分享一篇关于springmvc配置线程池Executor做多线程并发操作的代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
recommend-type

C++递归算法实例代码

主要介绍了C++递归算法实例代码,还是比较不错的,运用了递归算法解决相关问题,这里分享给大家,需要的朋友可以参考下。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

前端深拷贝 和浅拷贝有哪些方式,你在哪里使用过

前端深拷贝和浅拷贝的方式有很多,下面列举几种常用的方式: 深拷贝: 1. JSON.parse(JSON.stringify(obj)),该方法可以将对象序列化为字符串,再将字符串反序列化为新的对象,从而实现深拷贝。但是该方法有一些限制,例如无法拷贝函数、RegExp等类型的数据。 2. 递归拷贝,即遍历对象的每个属性并进行拷贝,如果属性值是对象,则递归进行拷贝。 3. 使用第三方库如lodash、jQuery等提供的深拷贝方法。 浅拷贝: 1. Object.assign(target, obj1, obj2, ...),该方法可以将源对象的属性浅拷贝到目标对象中,如果有相同的属性,则会
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。