线程池

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 lock
	pthread_mutex_t * pLocker;
	//producer thread condition
	pthread_cond_t * pCond;
	//针对指定producer的worker活动线程数
	int*			 pBusyNum;
	//worker thread
	IThreadProc* pTheadProc;
	//worker 要处理的数据
	void * param;
	//数据长度
	int    dataSize;
} struData ;

class CThreadPool
{
public:
	CThreadPool();
	virtual ~CThreadPool();
private:
	//线程id
	map<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表示不唤醒
	int	CreatePool( 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 ms
	select(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;
	}
}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值