1、今天见论坛里有问怎么样实现线程池。碰巧原来写过一个类似的。现在来说说。(下面的全是个人理解,不见得是正确的。)1。先来说说线程池。为什么要使用线程池?因为创建线程和释放线程是要消耗系统资源的,如果要完成一个工作要不停的创建和释放线程必然会造成很大的系统资源的浪费,所以用线程池。在线程本次工作完成后,不释放线程,让线程等待。再有需要让线程去完成的工作时就把原来创建的线程取过来继续使用。这样节省了重复的创建释放线程的过程。2。如何实现功能。根据上面的理解我们来实现这些工作。A.我们先要创建一个容器来装这些已经创建的线程。B.然后我们需要用一套机制来让我们知道容器中的线程哪个是空闲的。哪个正在工作。
2、开始动手写吧./.h 文件#ifndef MyThreadPoolH#define MyThreadPoolH#include /定义通讯消息#define TP_AddThread WM_USER + 1001 /向容器添加一个线程#define TP_DeleteThread WM_USER + 1002 /删除容器中的一个线程#define TP_GetFreeThread WM_USER + 1003 /获取一个空闲线程#define TP_GetThreadCount WM_USER + 1004 /得到容器中的线程总数class MyThreadPool : public TObj
3、ectprivate:HANDLE FHandle;/线程池的句柄 用来接收通讯消。TList *FThreadList; /用一个 TList 来做容器bool FError; /是否出现错误void _fastcall (TMessage /消息处理函数long _fastcall FGetThreadCount(void);/得到容器中线程的总数public:_fastcall MyThreadPool();_fastcall MyThreadPool();_published:/发布属性_property HNDLE Handle=read=FHandle;_property bool
4、 Error=read=FError;/_property TList *ThreadList=read=FThreadList;/如果有必要把容器发布出来 !但会降低安全性!_property long ThreadCount=read=GetFreeThread;#endif/.cpp#include #pragma hdrstop#include “MyThreadPool.h“#pragma package(smart_init)_fastcall MyThreadPool:MyThreadPool()FError=false;FHandle=AllocateHWnd(MyProc);
5、/创建一个窗口句柄来处理消息if(FHandle=NULL)FError=true;return;FThreadList=new TList;/创建容器if(FThreadList=NULL)FError=true;return;_fastcall MyThreadPool:MyThreadPool()if(FHandle!=NULL)/释放句柄DeallocateHWnd(FHandle);if(FThreadList!=NULL)/释放容器/这里只把容器中的线程指针给删除了。/中间的线程并没有释放。要释放需要自己添加代码FThreadList-Clear();delete FThreadL
6、ist;/处理消息void _fastcall MyThreadPool:MyProc(TMessage int ret;switch(Message.Msg)case TP_AddThread:/添加线程的时候消息的 WParam 参数为线程指针pThread=(void *)Message.WParam;ret=FThreadList-Add(pThread);Message.Result=ret;/返回线程指针在容器中的 indexreturn;case TP_DeleteThread:/删除线程时消息的 WParam 参数为线程指针pThread=(void *)Message.WPa
7、ram;ret=FThreadList-IndexOf(pThread);/如果线程指针不在容器中返回 -1,成功删除返回 1if(ret=-1)Message.Result=-1; elseFThreadList-Delete(ret);Message.Result=1;return;case TP_GetFreeThread:/得到一个空闲的线程, 如果有空闲消息返回值为线程指针。/一但线程给取出线程的 Working 属性就倍设置成 true;for(int i=0;iCount;i+)pThreadFThreadList-Itemsi;if(TMyThread *)pThread)-W
8、orking=false)(TMyThread *)pThread)-Working=true;Message.Result=(long)pThread;return;Message.Result=0;return;case TP_GetThreadCount:/返回容器中的总数Message.Result=FThreadList-Count;return; tryDispatch(if(Message.Msg=WM_QUERYENDSESSION)Message.Result=1;catch(.);3。我们还需要定制一个自己的线程类来配合上面的 ThreadPool 来使用class TMy
9、Thread : public TThreadprivate:bool FWorking;HANDLE PoolHandleprotected:void _fastcall Execute();public:_fastcall TMyThread(bool CreateSuspended,HANDLE hHandle/*线程池的句柄*/);_published:/发布属性_property bool Working=read=FWorking,write=FWorking; /线程是否空闲;_fastcall TMyThread:TMyThread(bool CreateSuspended,H
10、ANDLE hHandle): TThread(CreateSuspended)PoolHandle=hHandle;FWorking=false; void _fastcall TMyThread:Execute()while(!Terminated)FWorking=true;/工作代码/。FWorking=false;this-Suspend();:SendMessage(PoolHandle,TP_DeleteThread,(long)this,0);/在线程池的容器中删除本线程return;/线程结束4。下面来演示一下如何使用/1.创建线程池对象MyThreadPool *pMyTP
11、=new MyThreadPool;if(!pMyTP | pMyTP-Error)/创建出错。/。处理代码 /2.创建 N 个 TMyThread 线程对象, 并加入线程池TMyThread *pThread;for(int i=0;iHandle);:SendMessage(pMyTP-Handle,TP_AddThread,(long)pThread,0); /3.从线程池中去空闲线程TMyThread *pThread;pThread=(TMyThread *):SendMessage(pMyTP-Handle,TP_GetFreeThread,0,0);if(pThread)/如果有空闲线程pThread-Resume(); 这样就大致实现了线程池的功能。这种东西我已经用在了程序里了。效果还不错节省了不少资源。但是可能和书上说的线程池还是有很大差别的。我们暂且叫它线程池 A。反正已经达到我开始的时候设计它的目的,节省了资源。就当是抛砖引玉吧。希望这些代码能给兄弟们一点启发,对兄弟门有用。