//线程工作类与任务接通
#include<pthread.h>
#include<iostream>
#include<vector>
using namespace std;
//互斥类
class CThreadMutex
{
friend class CCondition;
public:
CThreadMutex()
{
pthread_mutex_init(&m_pthreadMutex, NULL);
}
~CThreadMutex()
{
}
void Lock()
{
pthread_mutex_lock(&m_pthreadMutex);
}
void Unlock()
{
pthread_mutex_unlock(&m_pthreadMutex);
}
pthread_mutex_t& GetMutex()
{
return m_pthreadMutex;
}
private:
pthread_mutex_t m_pthreadMutex;
};
//条件变量类
class CCondition //条件变量类
{
public:
CCondition()
{
pthread_cond_init(&m_cond, NULL);
}
~CCondition()
{
//delete m_lock;
}
void Lock()
{
m_lock.Lock();
}
void Unlock()
{
m_lock.Unlock();
}
void Wait()
{
pthread_cond_wait(&m_cond, &m_lock.GetMutex());
}
void Signal()
{
pthread_cond_signal(&m_cond);
}
private:
pthread_cond_t m_cond;
CThreadMutex m_lock; //互斥锁
};
//线程基类
class CThread
{
private:
pthread_t m_ThreadID;
int m_ThreadState; //the state of the thread
public:
CThread();
virtual ~CThread();
virtual void Run()=0;
static void* ThreadFunction(void* par); //调用函数run()
//Start to execute the thread 线程的执行入口,其调用ThreadFunction()函数,
void Start()
{
cout<<"~~~~start~~~~"<<endl;
if( pthread_create(&m_ThreadID,NULL,ThreadFunction,this) == 0)
cout<<"~~~xianchengchuangjianchenggong!!!!!"<<endl;
}
int GetThreadState(void){return m_ThreadState;}
int GetThreadID(void){return m_ThreadID;}
};
CThread::CThread()
{
m_ThreadID = 0;
m_ThreadState = 0;
Start();
}
void* CThread::ThreadFunction(void* par)
{
((CThread*)par)->Run();
}
CThread::~CThread()
{
}
//任务类
class CJob
{
public:
CJob( void );
virtual ~CJob();
virtual void Run () = 0;
};
CJob::CJob(void)
{
cout<<"CJob's constructor"<<endl;
}
CJob::~CJob(){
}
//CWorkerThread类
class CThreadPool;
class CWorkerThread:public CThread
{
private:
class CThreadPool* m_ThreadPool;
CJob*
m_Job;
CThreadMutex m_VarMutex;
bool
m_IsEnd;
public:
//CThreadMutex m_WorkMutex;
CCondition m_JobCond;
CWorkerThread();
~CWorkerThread();
void Run();
void SetJob(CJob* job);
void SetThreadPool(CThreadPool* thrpool);
};
CWorkerThread::CWorkerThread()
{
m_Job = NULL;
m_ThreadPool = NULL;
m_IsEnd = false;
}
CWorkerThread::~CWorkerThread()
{
//if(NULL != m_Job)
//delete m_Job;
//if(m_ThreadPool != NULL)
//delete m_ThreadPool;
}
void CWorkerThread::SetJob(CJob* job)
{
m_VarMutex.Lock();
m_Job = job;
m_VarMutex.Unlock();
m_JobCond.Signal();
}
void CWorkerThread::SetThreadPool(CThreadPool* thrpool)
{
m_VarMutex.Lock();
m_ThreadPool = thrpool;
m_VarMutex.Unlock();
}
//线程池类
class CThreadPool
{
private:
unsigned int m_InitNum; //Normal thread num;
protected:
CWorkerThread* GetIdleThread(void);
void AppendToIdleList(CWorkerThread* jobthread);
void MoveToBusyList(CWorkerThread* idlethread);
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
CCondition m_IdleCond; //m_IdleCond is used to sync idle thread list
vector< CWorkerThread* > m_BusyList; //Thread List
vector< CWorkerThread* > m_IdleList; //Idle List
vector< CWorkerThread* >::iterator ite;
CThreadPool();
CThreadPool(int initnum);
virtual ~CThreadPool(){}
void MoveToIdleList(CWorkerThread* busythread);
void SetInitNum(int initnum){m_InitNum = initnum;}
int GetInitNum(void){return m_InitNum;}
void Run(CJob* job);
};
CThreadPool::CThreadPool()
{
m_InitNum=10;
for(int i=0;i<m_InitNum;i++)
{
CWorkerThread* thr = new CWorkerThread();
AppendToIdleList(thr);
thr->SetThreadPool(this);
}
}
void CThreadPool::AppendToIdleList(CWorkerThread* jobthread)
{
m_IdleMutex.Lock();
m_IdleList.push_back(jobthread);
m_IdleMutex.Unlock();
}
void CThreadPool::MoveToBusyList(CWorkerThread* idlethread)
{
m_IdleMutex.Lock();
m_BusyMutex.Lock();
m_BusyList.push_back(idlethread);
m_BusyMutex.Unlock();
for(ite=m_IdleList.begin();ite!=m_IdleList.end();ite++)
{
if(*ite==idlethread)
break;
}
m_IdleList.erase(ite);
m_IdleMutex.Unlock();
}
void CThreadPool::MoveToIdleList(CWorkerThread* busythread)
{
m_BusyMutex.Lock();
m_IdleMutex.Lock();
m_IdleList.push_back(busythread);
m_IdleMutex.Unlock();
for(ite=m_BusyList.begin();ite!=m_BusyList.end();ite++)
{
if(*ite==busythread)
break;
}
m_BusyList.erase(ite);
m_BusyMutex.Unlock();
m_IdleCond.Signal();
}
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();
m_IdleMutex.Unlock();
return thr;
}
m_IdleMutex.Unlock();
return NULL;
}
void CThreadPool::Run(CJob* job)
{
//assert(job!=NULL);
CWorkerThread* idlethr = GetIdleThread();
if(idlethr !=NULL)
{
idlethr->m_JobCond.Lock();
MoveToBusyList(idlethr);
idlethr->SetJob(job);
}
}
void CWorkerThread::Run()
{
for(;;)
{
cout<<"~~~~~~waiting!!!!!!"<<endl;
while(m_Job == NULL)
m_JobCond.Wait();
m_Job->Run();
// cout<<"~~~job is done!!!!!"<<endl;
m_Job=NULL;
m_ThreadPool->MoveToIdleList(this);
m_JobCond.Unlock();
}
}
class CXJob:public CJob
{
public:
CXJob(){}
~CXJob(){}
void Run() {
cout<<"The Job comes from CXJOB/n"<<endl;
sleep(2);
}
};
int main()
{
int i;
CThreadPool thrdpool1;
CXJob* job = new CXJob();
for(i=0;i<10;i++)
thrdpool1.Run(job);
while(1)
sleep(100);
return 0;
}