分享
 
 
 

自己实现一个“线程池”

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

今天见论坛里有问怎么样实现线程池。碰巧原来写过一个类似的。现在来说说。(下面的全是个人理解,不见得是正确的。)

1。先来说说线程池。为什么要使用线程池?

因为创建线程和释放线程是要消耗系统资源的,如果要完成一个工作要不停的创建和释放线程必然会造成很大的系统资源的浪费,所以用线程池。在线程本次工作完成后,不释放线程,让线程等待。再有需要让线程去完成的工作时就把原来创建的线程取过来继续使用。这样节省了重复的创建释放线程的过程。

2。如何实现功能。

根据上面的理解我们来实现这些工作。

A.我们先要创建一个容器来装这些已经创建的线程。

B.然后我们需要用一套机制来让我们知道容器中的线程哪个是空闲的。哪个正在工作。

开始动手写吧.

//.h文件

#ifndef MyThreadPoolH

#define MyThreadPoolH

#include <Classes.hpp>

//定义通讯消息

#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 TObject

{

private:

HANDLE FHandle;//线程池的句柄 用来接收通讯消。

TList *FThreadList; //用一个TList来做容器

bool FError; //是否出现错误

void __fastcall (TMessage &Message);//消息处理函数

long __fastcall FGetThreadCount(void);//得到容器中线程的总数

public:

__fastcall MyThreadPool();

__fastcall ~MyThreadPool();

__published:

//发布属性

__property HNDLE Handle={read=FHandle};

__property bool Error={read=FError};

//__property TList *ThreadList={read=FThreadList};//如果有必要把容器发布出来 !但会降低安全性!

__property long ThreadCount={read=GetFreeThread};

};

#endif

//.cpp

#include <vcl.h>

#pragma hdrstop

#include "MyThreadPool.h"

#pragma package(smart_init)

__fastcall MyThreadPool::MyThreadPool()

{

FError=false;

FHandle=AllocateHWnd(MyProc);//创建一个窗口句柄来处理消息

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 FThreadList;

}

}

//处理消息

void __fastcall MyThreadPool::MyProc(TMessage &Message)

{

void *pThread;

int ret;

switch(Message.Msg)

{

case TP_AddThread://添加线程的时候消息的WParam参数为线程指针

pThread=(void *)Message.WParam;

ret=FThreadList->Add(pThread);

Message.Result=ret;//返回线程指针在容器中的index

return;

case TP_DeleteThread://删除线程时消息的WParam参数为线程指针

pThread=(void *)Message.WParam;

ret=FThreadList->IndexOf(pThread);

//如果线程指针不在容器中返回-1,成功删除返回1

if(ret==-1)

{

Message.Result=-1;

}

else

{

FThreadList->Delete(ret);

Message.Result=1;

}

return;

case TP_GetFreeThread://得到一个空闲的线程,如果有空闲消息返回值为线程指针。

//一但线程给取出线程的Working属性就倍设置成true;

for(int i=0;i<FThreadList->Count;i++)

{

pThreadFThreadList->Items[i];

if(((TMyThread *)pThread)->Working==false)

{

((TMyThread *)pThread)->Working=true;

Message.Result=(long)pThread;

return;

}

}

Message.Result=0;

return;

case TP_GetThreadCount://返回容器中的总数

Message.Result=FThreadList->Count;

return;

}

try

{

Dispatch(&Message);

if(Message.Msg==WM_QUERYENDSESSION)

{

Message.Result=1;

}

}

catch(...){};

}

3。我们还需要定制一个自己的线程类来配合上面的ThreadPool来使用

class TMyThread : public TThread

{

private:

bool FWorking;

HANDLE PoolHandle

protected:

void __fastcall Execute();

public:

__fastcall TMyThread(bool CreateSuspended,HANDLE hHandle/*线程池的句柄*/);

__published:

//发布属性

__property bool Working={read=FWorking,write=FWorking}; //线程是否空闲

};

__fastcall TMyThread::TMyThread(bool CreateSuspended,HANDLE 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=new MyThreadPool;

if(!pMyTP || pMyTP->Error)

{

//创建出错。

//。。。处理代码

}

//2.创建N个TMyThread线程对象,并加入线程池

TMyThread *pThread;

for(int i=0;i<N;i++)

{

pThread=new TMyThread(true,pMyTP->Handle);

::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。反正已经达到我开始的时候设计它的目的,节省了资源。

就当是抛砖引玉吧。希望这些代码能给兄弟们一点启发,对兄弟门有用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有