首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>系统管理>内核技术>正文

Linux下通用线程池的创建与使用(上)

http://www.oklinux.cn  2006-01-01  来源: 赛迪网技术社区  张中庆   会员收藏  游客收藏  【 】 

线程的状态可以分为四种,空闲、忙碌、挂起、终止(包括正常退出和非正常退出)。由于目前Linux线程库不支持挂起操作,因此,我们的此处的挂起操作类似于暂停。如果线程创建后不想立即执行任务,那么我们可以将其“暂停”,如果需要运行,则唤醒。有一点必须注意的是,一旦线程开始执行任务,将不能被挂起,其将一直执行任务至完毕。

线程类的相关操作均十分简单。线程的执行入口是从Start()函数开始,其将调用函数ThreadFunction,ThreadFunction再调用实际的Run函数,执行实际的任务。

CThreadPool

CThreadPool是线程的承载容器,一般可以将其实现为堆栈、单向队列或者双向队列。在我们的系统中我们使用STL Vector对线程进行保存。CThreadPool的实现代码如下:

class CThreadPool 

{ 

friend class CWorkerThread; 

private: 

unsigned int m_MaxNum; //the max thread num that can create at the same time 

unsigned int m_AvailLow; //The min num of idle thread that shoule kept 

unsigned int m_AvailHigh; //The max num of idle thread that kept at the same time 

unsigned int m_AvailNum; //the normal thread num of idle num; 

unsigned int m_InitNum; //Normal thread num; 

protected: 

CWorkerThread* GetIdleThread(void); 

void AppendToIdleList(CWorkerThread* jobthread); 

void MoveToBusyList(CWorkerThread* idlethread); 

void MoveToIdleList(CWorkerThread* busythread); 

void DeleteIdleThread(int num); 

void CreateIdleThread(int num); 

public: 

CThreadMutex m_BusyMutex; //when visit busy list,use m_BusyMutex to lock and unlock 

CThreadMutex m_IdleMutex; //when visit idle list,use m_IdleMutex to lock and unlock 

CThreadMutex m_JobMutex; //when visit job list,use m_JobMutex to lock and unlock 

CThreadMutex m_VarMutex; 

CCondition m_BusyCond; //m_BusyCond is used to sync busy thread list 

CCondition m_IdleCond; //m_IdleCond is used to sync idle thread list 

CCondition m_IdleJobCond; //m_JobCond is used to sync job list 

CCondition m_MaxNumCond; 

vector<CWorkerThread*> m_ThreadList; 

vector<CWorkerThread*> m_BusyList; //Thread List 

vector<CWorkerThread*> m_IdleList; //Idle List 

CThreadPool(); 

CThreadPool(int initnum); 

virtual ~CThreadPool(); 

void SetMaxNum(int maxnum){m_MaxNum = maxnum;} 

int GetMaxNum(void){return m_MaxNum;} 

void SetAvailLowNum(int minnum){m_AvailLow = minnum;} 

int GetAvailLowNum(void){return m_AvailLow;} 

void SetAvailHighNum(int highnum){m_AvailHigh = highnum;} 

int GetAvailHighNum(void){return m_AvailHigh;} 

int GetActualAvailNum(void){return m_AvailNum;} 

int GetAllNum(void){return m_ThreadList.size();} 

int GetBusyNum(void){return m_BusyList.size();} 

void SetInitNum(int initnum){m_InitNum = initnum;} 

int GetInitNum(void){return m_InitNum;} 

void TerminateAll(void); 

void Run(CJob* job,void* jobdata); 

}; 

CThreadPool::CThreadPool() 

{ 

m_MaxNum = 50; 

m_AvailLow = 5; 

m_InitNum=m_AvailNum = 10 ; 

m_AvailHigh = 20; 

m_BusyList.clear(); 

m_IdleList.clear(); 

for(int i=0;i<m_InitNum;i++){ 

CWorkerThread* thr = new CWorkerThread(); 

thr->SetThreadPool(this); 

AppendToIdleList(thr); 

thr->Start(); 

} 

} 

CThreadPool::CThreadPool(int initnum) 

{ 

assert(initnum>0 && initnum<=30); 

m_MaxNum = 30; 

m_AvailLow = initnum-10>0?initnum-10:3; 

m_InitNum=m_AvailNum = initnum ; 

m_AvailHigh = initnum+10; 

m_BusyList.clear(); 

m_IdleList.clear(); 

for(int i=0;i<m_InitNum;i++){ 

CWorkerThread* thr = new CWorkerThread(); 

AppendToIdleList(thr); 

thr->SetThreadPool(this); 

thr->Start(); //begin the thread,the thread wait for job 

} 

} 

CThreadPool::~CThreadPool() 

{ 

TerminateAll(); 

} 

void CThreadPool::TerminateAll() 

{ 

for(int i=0;i < m_ThreadList.size();i++) { 

CWorkerThread* thr = m_ThreadList[i]; 

thr->Join(); 

} 

return; 

} 

CWorkerThread* CThreadPool::GetIdleThread(void) 

{ 

while(m_IdleList.size() ==0 ) 

m_IdleCond.Wait(); 

m_IdleMutex.Lock(); 

if(m_IdleList.size() > 0 ) 

{ 

CWorkerThread* thr = (CWorkerThread*)m_IdleList.front(); 

printf("Get Idle thread %dn",thr->GetThreadID()); 

m_IdleMutex.Unlock(); 

return thr; 

} 

m_IdleMutex.Unlock(); 

return NULL; 

} 



//add an idle thread to idle list 

void CThreadPool::AppendToIdleList(CWorkerThread* jobthread) 

{ 

m_IdleMutex.Lock(); 

m_IdleList.push_back(jobthread); 

m_ThreadList.push_back(jobthread); 

m_IdleMutex.Unlock(); 

} 

//move and idle thread to busy thread 

void CThreadPool::MoveToBusyList(CWorkerThread* idlethread) 

{ 

m_BusyMutex.Lock(); 

m_BusyList.push_back(idlethread); 

m_AvailNum--; 

m_BusyMutex.Unlock(); 

m_IdleMutex.Lock(); 

vector<CWorkerThread*>::iterator pos; 

pos = find(m_IdleList.begin(),m_IdleList.end(),idlethread); 

if(pos !=m_IdleList.end()) 

m_IdleList.erase(pos); 

m_IdleMutex.Unlock(); 

} 

void CThreadPool::MoveToIdleList(CWorkerThread* busythread) 

{ 

m_IdleMutex.Lock(); 

m_IdleList.push_back(busythread); 

m_AvailNum++; 

m_IdleMutex.Unlock(); 

m_BusyMutex.Lock(); 

vector<CWorkerThread*>::iterator pos; 

pos = find(m_BusyList.begin(),m_BusyList.end(),busythread); 

if(pos!=m_BusyList.end()) 

m_BusyList.erase(pos); 

m_BusyMutex.Unlock(); 

m_IdleCond.Signal(); 

m_MaxNumCond.Signal(); 

} 

//create num idle thread and put them to idlelist 

void CThreadPool::CreateIdleThread(int num) 

{ 

for(int i=0;i<num;i++){ 

CWorkerThread* thr = new CWorkerThread(); 

thr->SetThreadPool(this); 

AppendToIdleList(thr); 

m_VarMutex.Lock(); 

m_AvailNum++; 

m_VarMutex.Unlock(); 

thr->Start(); //begin the thread,the thread wait for job 

} 

} 

void CThreadPool::DeleteIdleThread(int num) 

{ 

printf("Enter into CThreadPool::DeleteIdleThreadn"); 

m_IdleMutex.Lock(); 

printf("Delete Num is %dn",num); 

for(int i=0;i<num;i++){ 

CWorkerThread* thr; 

if(m_IdleList.size() > 0 ){ 

thr = (CWorkerThread*)m_IdleList.front(); 

printf("Get Idle thread %dn",thr->GetThreadID()); 

} 

vector<CWorkerThread*>::iterator pos; 

pos = find(m_IdleList.begin(),m_IdleList.end(),thr); 

if(pos!=m_IdleList.end()) 

m_IdleList.erase(pos); 

m_AvailNum--; 

printf("The idle thread available num:%d n",m_AvailNum); 

printf("The idlelist num:%d n",m_IdleList.size()); 

} 

m_IdleMutex.Unlock(); 

} 

void CThreadPool::Run(CJob* job,void* jobdata) 

{ 

assert(job!=NULL); 

//if the busy thread num adds to m_MaxNum,so we should wait 

if(GetBusyNum() == m_MaxNum) 

m_MaxNumCond.Wait(); 



if(m_IdleList.size()<m_AvailLow) 

{ 

if(GetAllNum()+m_InitNum-m_IdleList.size() < m_MaxNum ) 

CreateIdleThread(m_InitNum-m_IdleList.size()); 

else 

CreateIdleThread(m_MaxNum-GetAllNum()); 

} 

CWorkerThread* idlethr = GetIdleThread(); 

if(idlethr !=NULL) 

{ 

idlethr->m_WorkMutex.Lock(); 

MoveToBusyList(idlethr); 

idlethr->SetThreadPool(this); 

job->SetWorkThread(idlethr); 

printf("Job is set to thread %d n",idlethr->GetThreadID()); 

idlethr->SetJob(job,jobdata); 

} 

}

()

共3页: 上一页 [1] [2] 3 下一页

上一篇:Linux桌面系统开发者求同存异谋发展   下一篇:Linux下通用线程池的创建与使用(下)


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·Linux桌面系统开发者求同存异谋发展
·Linux下通用线程池的创建与使用(下)
·教你制作可以随身携带的FreeBSD系统
·GNU/Linux开发者需要从桌面突破
·用Perl管理Linux操作系统的配置文件
·如何编译一个操作系统内核-Ubuntu方式
·Linux的系统过程中的LILO和GRUB(上)
·精华:升级Linux操作系统内核奋斗记
·Linux系统中使用SystemTap调试内核
·使用Ioctl向Linux内核传递参数的方法
·Liunx操作系统编程之Const使用详解
·Linux中Gnome与KDE字体大小不同的解决
·Linux操作系统下的软中断问题分析
·Linux操作系统下的汇编程序设计简介
·Linux的高效的数据传输技术-Relay
·Linux系统内核定时器机制详解(下)
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·学习园地:Linux系统内核中判断大小的
·系统编译:如何给Make命令来传递参数
·Linux 2.6内核中sysfs文件系统简单概述
·Fedora 8 Linux系统的内核配置注意事项
·升级Linux内核的一般步骤方法
·Linux发行版知识普及:三个版本的CPUID
·编译安装Virtualbox驱动模块
· Linux系统的内核解读入门
·新手学堂 Linux系统的内核解读入门
·Linux系统内核中网络参数的意义及其应
·走向Linux系统高手之路 内核编译过程解
·Linux系统中安装内核的方法详细介绍
  阅读排行
· 深入理解LINUX内核中文版下载地址
·基于S3C44B0微处理器的uClinux内核引导
·Kernel command using Linux system ca
·Linux 2.6内核如何武装Fedora Core 2
·Process priority and control on AIX
·Linux操作系统的内核编译内幕详解
·推荐:Linux用户态与内核态的交互
·通过振动向Linux ThinkPad传输信息
·Linux操作系统源代码详细分析(二)
·Linux系统内核接收以太帧的处理程序
·Linux and symmetric multiprocessing
·主流嵌入式Linux系统下GUI解决方案
·揭秘Linux内核调试器之内幕
·用命令行加挂Linux的文件系统简介
·Linux内核和核心OS组件的测试与分析
网摘收藏: