线程池

来源:互联网 发布:秒领棒棒糖软件 编辑:程序博客网 时间:2024/05/21 01:53

threadpool.h:


// ThreadPool.h: interface for the CThreadPool class.////////////////////////////////////////////////////////////////////////#ifndef __THREADPOOL_H__#define __THREADPOOL_H__#include <pthread.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <map>#include <set>#include <list>#include <iostream>using namespace std;namespace Model{class IThreadProc{public:virtual ~IThreadProc(){};public:virtual void Process( int index,void* param, int size ) = 0 ;};//待处理数据typedef struct _data{//还有剩余数据吗?bool* bDataRemain;//producer准备好接受结束信号了吗?bool *bReady;//producer thread lockpthread_mutex_t * pLocker;//producer thread conditionpthread_cond_t * pCond;//针对指定producer的worker活动线程数int* pBusyNum;//worker threadIThreadProc* pTheadProc;//worker 要处理的数据void * param;//数据长度int    dataSize;} struData ;class CThreadPool{public:CThreadPool();virtual ~CThreadPool();private://线程idmap<int , pthread_t >  m_mapTids;//线程池参数typedef struct _thread_param{CThreadPool* pThis;//唤醒定时int timer ;//工作中的线程数int iBusy;pthread_mutex_t * pMutex;pthread_cond_t * pCond;bool bExit;//tid映射map<int , pthread_t >*  pTids;list< struData > * pDataList;//create 参数void * param;} thread_param_struct;//线程函数参数thread_param_struct m_struThreadParam;//条件等待互斥锁mutable pthread_mutex_t m_mutex;//线程等待条件mutable pthread_cond_t m_condition;//待处理数据量mutable unsigned int m_iDataCount;//待处理数据列表mutable list< struData > m_dataList;//线程数volatile int m_threadCount;private://线程函数static void * ThreadProc( void * param );//分配数据缓存char * AllocBuf( int size );//释放数据缓存void FreeBuf( char* &data );protected://初始化线程资源virtual int InitThreads( int timer , void* param );public:// 启动线程// threadCount : 启动线程数// pTheadProc :  线程得到信号后执行的处理函数// timer :  是否定时唤醒线程,timer<=0表示不唤醒intCreatePool( unsigned int threadCount, int timer = 0 , void * param = NULL );// 停止线程virtual int StopPool( void );// 设置线程的休眠时间,单位:毫秒,只对下次执行后的等待有效void SetSleepTime( int t ) ;void mySleep(int ms);void freeListMem() const{pthread_mutex_lock(&m_mutex);if(m_dataList.empty()){list< struData >().swap(m_dataList);}pthread_mutex_unlock(&m_mutex);}public:// 通知线程virtual int Dispatch(struData* pData) const;// 通知所有线程virtual int DispatchAll(struData* pData = NULL);// 是否还有线程在工作bool isBusy();//线程数int  getThreadCount();};}#endif 
threadpool.cpp

// ThreadPool.cpp: implementation of the CThreadPool class.////////////////////////////////////////////////////////////////////////#include "Common/ThreadPool.h"namespace Model{//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CThreadPool::CThreadPool(){m_iDataCount = 0 ;m_threadCount = 0;}CThreadPool::~CThreadPool(){pthread_cond_destroy(&m_condition);pthread_mutex_destroy(&m_mutex);}int CThreadPool::CreatePool( unsigned int threadCount, int timer , void * param ){if( 0 != InitThreads(timer, param) ){return -1;}pthread_t tid;for(unsigned int i = 0 ; i< threadCount; i++){if( 0 != pthread_create(&tid,NULL,ThreadProc, &m_struThreadParam )){StopPool();m_mapTids.clear();return -1;}m_mapTids.insert(pair<int,pthread_t> (i, tid ));}sleep(1);m_threadCount = threadCount;return 0 ;}void * CThreadPool::ThreadProc( void * param ){thread_param_struct *pParamStru = (thread_param_struct*) param;map<int , pthread_t >* pTids = pParamStru->pTids;map<int , pthread_t >::iterator iter;//当前线程序号int index = -1;//当前线程状态及处理数据的参数副本struData dataParam;dataParam.pBusyNum = NULL;dataParam.bDataRemain = NULL;dataParam.pCond = pParamStru->pCond;dataParam.pLocker = pParamStru->pMutex;pthread_t tid = pthread_self();for(iter =pTids->begin();iter!=pTids->end();iter++){if(tid==iter->second){index = iter->first;break;}}if(index==-1){return NULL;}while( !pParamStru->bExit ){   //设置了定时唤醒if( pParamStru->timer > 0 ) {pParamStru->pThis->mySleep( pParamStru->timer );if(pParamStru->pDataList->empty())continue;}        pthread_mutex_lock(pParamStru->pMutex);        pParamStru->iBusy--;        if(dataParam.pBusyNum)        {        (*dataParam.pBusyNum)--;if((*dataParam.pBusyNum)==0&&!(*dataParam.bDataRemain) ){        pthread_mutex_lock(dataParam.pLocker);*(dataParam.bReady) = true;//处理完毕,发信号pthread_cond_signal(dataParam.pCond);pthread_mutex_unlock(dataParam.pLocker);}        }        //当待处理数据为空时才开始等待while( pParamStru->pDataList->empty() && pParamStru->timer <= 0 ){pthread_cond_wait(pParamStru->pCond,pParamStru->pMutex);   }        if(pParamStru->bExit)        {        pthread_mutex_unlock(pParamStru->pMutex);        break;        }        pParamStru->iBusy++;//取出数据        dataParam = pParamStru->pDataList->front();        //从待处理队列中移除pParamStru->pDataList->pop_front();//printf("list_buf size:%d,record size:%d.\n",pParamStru->pDataList->size(),*(pParamStru->pListSize));pthread_mutex_unlock(pParamStru->pMutex);        //处理数据if( dataParam.pTheadProc != NULL ){dataParam.pTheadProc->Process(index,dataParam.param,dataParam.dataSize );}}return NULL;}void CThreadPool::SetSleepTime( int t ){pthread_mutex_lock(&m_mutex);m_struThreadParam.timer = t ;pthread_mutex_unlock(&m_mutex);return ;}void CThreadPool::mySleep(int ms){struct timeval delay;delay.tv_sec = 0;delay.tv_usec = ms * 1000; // 1 msselect(0, NULL, NULL, NULL, &delay);}int CThreadPool::Dispatch( struData* pData) const{//传入空指针会检查是否退出if(pData==NULL){//压入处理队列pthread_mutex_lock(&m_mutex);struData tmpData;tmpData.pTheadProc = NULL;m_dataList.push_back(tmpData);        if(tmpData.pBusyNum)        {        (*tmpData.pBusyNum)++;        }//printf("dispatch , list size:%d \n" , m_iDataCount);pthread_mutex_unlock(&m_mutex);}else{//压入处理队列pthread_mutex_lock(&m_mutex);m_dataList.push_back( *pData );        if(pData->pBusyNum)        {        (*pData->pBusyNum)++;        }//printf("dispatch , list size:%d \n" , m_iDataCount);pthread_mutex_unlock(&m_mutex);}pthread_cond_signal(&m_condition);return 0 ;}int CThreadPool::DispatchAll( struData* pData ){//传入空指针会检查是否退出if(pData==NULL){//压入处理队列pthread_mutex_lock(&m_mutex);struData tmpData;tmpData.pTheadProc = NULL;m_dataList.push_back(tmpData);//printf("dispatch , list size:%d \n" , m_iDataCount);pthread_mutex_unlock(&m_mutex);}else{pthread_mutex_lock(&m_mutex);m_dataList.push_back( *pData );//printf("dispatch all, list size:%d \n" , m_iDataCount);pthread_mutex_unlock(&m_mutex);}pthread_cond_broadcast(&m_condition);return 0 ;}int CThreadPool::InitThreads(int timer , void* param ){int error ;error = pthread_mutex_init(&m_mutex,NULL);if( error != 0 ){return -1;}error = pthread_cond_init(&m_condition,NULL);if( error != 0 ){return -1;}//定时唤醒时间m_struThreadParam.timer = timer ;//传递参数m_struThreadParam.param = param ;//是否接受到退出信号m_struThreadParam.bExit = false ;//tid表m_struThreadParam.pTids = &m_mapTids;//线程锁m_struThreadParam.pMutex = &m_mutex;m_struThreadParam.pCond = &m_condition;//待处理数据列表m_struThreadParam.pDataList = &m_dataList;m_struThreadParam.pThis = this;return 0;}bool CThreadPool::isBusy(){bool bBusy;pthread_mutex_lock(&m_mutex);if( m_struThreadParam.iBusy>0){bBusy = true;}else{bBusy = false;}pthread_mutex_unlock(&m_mutex);return bBusy;}int  CThreadPool::getThreadCount(){return m_threadCount;}int CThreadPool::StopPool( void ){m_struThreadParam.bExit = true;SetSleepTime(1);for ( unsigned int i = 0 ; i< m_mapTids.size(); i++ ){DispatchAll();}int *pExitcode;for ( unsigned int i = 0 ; i< m_mapTids.size(); i++ ){pthread_join( m_mapTids[i] , (void **)&pExitcode);}m_mapTids.clear();while(!m_dataList.empty()){m_dataList.pop_front();}return 0 ;}char * CThreadPool::AllocBuf( int size ){if( size <= 0 ){return NULL;}else{return new char[size];}}void CThreadPool::FreeBuf( char* &data ){if( data != NULL ){delete [] data ;data  = NULL;}}}



原创粉丝点击