一个模板线程池,没有使用信号灯,互斥体等同步对象。
主要思路是初始化一个管理线程,管理线程通过消息协调任务链表和工作线程之间如何更好的工作,消息通信使用PostThreadMessage。
下面是模板线程池源代码
下面介绍如何使用这个模板线程池
1.任务类和模板实例化线程池类的定义及其实现
- /*======================================================================
- Copyright (c) 2010,zyq5945@126.com
- All rights reserved.
- 文件名称:MyThreadPool.h
- 摘 要:任务类和模板实例化线程池类的定义
- 当前版本:1.00
- 作 者:zyq5945@126.com(注意把中文字符换成英文字符)
- 完成日期:2010年6月26日
- 发布Blog:http://blog.csdn.net/zyq5945/
- ======================================================================*/
- #pragma once
- #include "MsgThreadPool.h"
- /*======================================================================
- 类名称: CTask
- 类说明: 自定义的测试任务类
- 如果类中有指针或者其他的类的话(深拷贝和浅拷贝),
- 没有把握最好是不要用编译器提供的默认拷贝构造函数和等号操作符
- ======================================================================*/
- class CTask
- {
- public:
- CTask();
- CTask(const CTask& rTask);
- CTask& operator =(const CTask& rTask);
- public:
- int m_nIndex;
- SYSTEMTIME m_cTime;
- };
- /*======================================================================
- 类名称: class CMyThreadPool : public CMsgThreadPool<CTask>
- 类说明: 具体是线程池类
- 需要在这个类的虚函数DoWork中实现要做的具体工作
- 也可以如此继承
- typedef CMsgThreadPool<CTask> CCTaskThreadPool;
- class CMyThreadPool : public CCTaskThreadPool
- ======================================================================*/
- class CMyThreadPool : public CMsgThreadPool<CTask>
- {
- public:
- CMyThreadPool(void);
- ~CMyThreadPool(void);
- protected:
- virtual void DoWork(CTask& rTask);
- };
实现代码很简单,下面是线程池任务处理过程
- /*======================================================================
- 函数名称: void CMyThreadPool::DoWork(CTask& rTask)
- 函数参数: T& t
- 一个需要处理的任务的引用
- 返回值: 无
- 函数说明: 具体的任务处理过程
- 注:请勿保存传递过来的参数指针
- ======================================================================*/
- void CMyThreadPool::DoWork(CTask& rTask)
- {
- CString strMsg;
- SYSTEMTIME st;
- st = rTask.m_cTime;
- strMsg.Format(_T("/tIndex:%08d/t%02d:%02d:%02d.%03d/t/tTID:%08x/n"),
- rTask.m_nIndex, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, GetCurrentThreadId());
- // 在调试窗口输出处理的任务
- OutputDebugString(strMsg);
- // 模拟线程处理消耗时间
- DWORD dwSleep = st.wMilliseconds > 500? st.wMilliseconds : 500;
- Sleep(dwSleep);
- }
2. 在对话框中实例化这个线程池类,并使用
a.添加头文件,本例中是
- #include "MyThreadPool.h"
b.实例化这个线程池类,本例中是添加到类成员变量中
- CMyThreadPool m_pool; // 线程池对象
c.初始化线程池对象
- // 初始化线程池对象
- VERIFY(m_pool.Init());
注:默认是初始化10个工作线程,你也可以在有空闲线程的时候调用SetThreadNum设置工作线程个数.
d.添加任务到线程池对象中
- // 测试加入任务
- SYSTEMTIME st;
- for (int i=0; i<100; i++)
- {
- CTask cTask;
- GetLocalTime(&st);
- st.wMilliseconds = st.wMilliseconds <500?
- st.wMilliseconds+i : st.wMilliseconds -i;
- static int s_nIndex = 0;
- cTask.m_nIndex = s_nIndex++;
- cTask.m_cTime = st;
- // 添加任务到线程池对象中
- m_pool.AddTask(cTask);
- }
在VC6.0中可能会有内存泄露(大小:工作线程个数*sizeof(任务类)),在VS2008SP1中测试没有内存泄露.
需要在各个VS版本测试,请修改模板线程池的析构函数的_MSC_VER宏为对应的VS版本即可.