LINUX C++ 线程池简单实现之双队列

来源:互联网 发布:软件开发流程 ppt 编辑:程序博客网 时间:2024/05/18 00:21

 线程池原理 

线程池的原理很简单,就是预先建立些空闲线程,并把它们投入睡眠中。当有任务到达时,就唤醒一个线程来处理,处理完后放回线程池中。因为线程池对空闲线程的维护,所以避免了对线程创建的开销,当频繁使用线程且处理工作量很小的情况下,使用线程池可以有效的提升系统性能。

2 线程池实现

线程池的实现主要分为四部分,线程的创建、添加任务到线程池中、子线程取出任务进行处理以及把执行完成的任务写回主线程。
   使用线程池的一般是为了防止主线程阻塞,所以把阻塞的任务(如读写磁盘等)交予子线程处理,实现方式一般分为双队列(同时使用互斥锁和条件变量)和管道两种。
  使用双队列的是因为在主线程非阻塞模式下,获取互斥锁时只能用try_lock的方式,从而不一定能获取到互斥锁,所以放任务时需要使用两个队列,当获取不到锁时就放入另一个队列,一个队列的任务执行完后,交换两队列;

3 双队列线程池程序实现:
  
头文件:

 18 #ifndef __CTHREAD

 19 #define __CTHREAD

 20 

 21 #include<queue>

 22 #include<string>

 23 #include<pthread.h>

 24 #include<iostream>

 25 using namespace std;

 26 

 27

 28 class CTask

 29 {

 30     protected:

 31         string m_strTaskName;

 32         void *m_ptrData;

 33     public:

 34 
    35

 36         CTask(){}

 37 

 38         CTask(string taskName)

 39         {

 40             this->m_strTaskName=taskName;

 41             m_ptrData=NULL;

 42         }

 43         virtual int Run()=0;

 44         void SetData(void *data);  //设置任务数据

 45 

 46 };

 47 

 48

 49 class CThreadPool

 50 {

 51     private:

 52          int m_threadNum;                       //线程数量  

 53 

 54          static pthread_mutex_t  m_threadMutex;

 55          static pthread_mutex_t  m_taskMutex;

 56          static pthread_cond_t   m_threadCond;

 57          static pthread_cond_t   m_taskCond;

 58 

 59          static queue<CTask*>* taskQueue1;        //任务队列1

 60          static queue<CTask*>* taskQueue2;        //任务队列2

 61          static queue<CTask*>* taskback;          //任务返回队列 

 62    public:

 63          CThreadPool(int);

 64          static int swapqueue(queue<CTask *>* &,queue<CTask*>* &);   //交换任务队列1和任务队列2的任务

 65          static void* ThreadFunc(void *arg);

 66          int Create();

 67          int AddTask(CTask*);           //加入任务

 68          CTask* GetTaskback();                   //返回任务

 69          int Check();

 70          static int clearQueue(queue<CTask*>*);

 71          ~CThreadPool();

 72 

 73 };

 74 

 75 #endif

cpp文件:
 
    18 #include"CThread.h"

 19 #include<string>

 20 #include<iostream>

 21 using namespace std;

 22 

 23 void CTask::SetData(void *data)

 24 {

 25     m_ptrData=data;

 26 }

 27 

 28 queue<CTask*>* CThreadPool::taskQueue2=new queue<CTask*>[1];

 29 queue<CTask*>* CThreadPool::taskQueue1=new queue<CTask*>[1];

 30 queue<CTask*>* CThreadPool::taskback=new queue<CTask*>[1];

 31 

 32 pthread_mutex_t CThreadPool::m_threadMutex=PTHREAD_MUTEX_INITIALIZER;

 33 pthread_mutex_t CThreadPool::m_taskMutex=PTHREAD_MUTEX_INITIALIZER;

 34 pthread_cond_t CThreadPool::m_threadCond=PTHREAD_COND_INITIALIZER;

 35 pthread_cond_t CThreadPool::m_taskCond=PTHREAD_COND_INITIALIZER;

 36 

 37 CThreadPool::CThreadPool(int threadNum)

 38 {

 39     this->m_threadNum=threadNum;

 40     Create();

 41 }

 42 

 43 int CThreadPool::swapqueue(queue<CTask*>* &a,queue<CTask*>* &b)  //交换两个队列

 44 {   

 45      queue<CTask*>* temp;

 46      temp=a;

 47      a=b;

 48      b=temp;   cout<<"swap!!!!!"<<endl;

 49 }

 50 

 51 void *CThreadPool::ThreadFunc(void *arg)   

 52 {

 53     pthread_t tid=pthread_self();

 54     while(1)

 55     {

 56         CTask *task;

 57         if(taskQueue1->empty()&&!taskQueue2->empty())

 58             swapqueue(taskQueue1,taskQueue2);

 59 

 60         pthread_mutex_lock(&m_threadMutex);

 61 

 62         if(taskQueue1->empty())

 63         {

 64            pthread_cond_wait(&m_threadCond,&m_threadMutex);

 65            pthread_mutex_unlock(&m_threadMutex);

 66            continue;

 67         }

 68 

 69         task=taskQueue1->front();

 70         taskQueue1->pop();

 71         pthread_mutex_unlock(&m_threadMutex);

 72 

 73         task->Run();

 74 

 75         pthread_mutex_lock(&m_taskMutex);

 76         taskback->push(task);

 77         //pthread_cond_signal(&m_taskCond);

 78         pthread_mutex_unlock(&m_taskMutex);

 79 

 80     }

 81     return 0;

 82 }

 83 

 84 int CThreadPool::AddTask(CTask *task)    //添加任务到线程池中

 85 {

 86     if(pthread_mutex_trylock(&m_threadMutex)==0)

 87     {

 88         taskQueue1->push(task);

 89         pthread_cond_signal(&m_threadCond);

 90         cout<<"add to queue1"<<endl;

 91         pthread_mutex_unlock(&m_threadMutex);

 92 

 93     }else

 94     {

 95         taskQueue2->push(task);

 96         pthread_cond_signal(&m_threadCond);

 97         cout<<"add to queue2"<<endl;

 98         pthread_mutex_unlock(&m_threadMutex);

 99     }

100 

101     return 0;

102 

103 }

104 

105 CTask* CThreadPool::GetTaskback()      //取出执行完的任务

106 {

107     CTask *task;

108 

109    // if(pthread_mutex_trylock(&m_taskMutex)==0)

110 

111     if(!taskback->empty())

112     {

113       task=taskback->front();

114       taskback->pop();

115       //pthread_mutex_unlock(&m_taskMutex);

116 

117       return task;

118 

119     }

120 

121     return NULL;

122 }

123 

124 int CThreadPool::Create()      //创建线程池

125 {

126     pthread_t tid=0;

127     for(int i=0;i<m_threadNum;i++)

128     {

129         if(pthread_create(&tid,NULL,ThreadFunc,NULL)!=0)

130         {

131              cout<<"pthead_create error";

132              return -1;

133         }

134     }

135     return 0;

136 }

137 

138 int CThreadPool::clearQueue(queue<CTask*> *a)   

139 {

140     while(!a->empty())

141     {

142        a->pop();

143     }

144 

145     delete a;

146     return 0;

147 }

148 

149 int CThreadPool::Check()     //防止有任务为执行

150 {

151    if(!taskQueue1->empty()||!taskQueue2->empty())

152        pthread_cond_signal(&m_threadCond);

153 }

154 

155 CThreadPool::~CThreadPool()

156 {

157     clearQueue(taskQueue1);

158     clearQueue(taskQueue2);

159     pthread_cond_destroy(&m_threadCond);

160 }

161 


测试文件:
    19 #include"CThread.cpp"

 20 #include<iostream>

 21 #include<sys/time.h>

 22 

 23 using namespace std;

 24 

 25 class CWorkTask:public CTask

 26 {

 27     public:

 28     CWorkTask(){}

 29     int Run()

 30     {

 31         cout<<(char*)this->m_ptrData<<endl;

 32         sleep(1);

 33         return 0;

 34     }

 35 };

 36 

 37 int main()

 38 {

 39     struct timeval begin,end;

 40 

 41     CWorkTask tt;

 42     char str[]="!!!!!!!!!!this is a test";

 43 

 44     tt.SetData((void*)str);

 45     CThreadPool threadpool(5);

 46 

 47     for(int i=0;i<10;i++)

 48     {

 49         threadpool.AddTask(&tt);

 50 

 51     }

 52 

 53      while(1)      //不让进程退出

 54      {

 55          sleep(10);

 56          threadpool.Check();

 57      }

 58 

 59 }

执行结果:[转载]LINUX <wbr> <wbr>C++ <wbr>线程池简单实现之双队列


0 0
原创粉丝点击