Linux C++ 简单线程池

本文参考:http://www.cnblogs.com/lidabo/p/3328646.html

global.h

#ifndef __GLOBAL_H__
#define __GLOBAL_H__

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <list>
#include <set>
#include <pthread.h>
using namespace std;

class Task
{
public:
	virtual ~Task() {};
	virtual void Run() = 0;
};

class Thread;
class ThreadMgr;

#endif	//__GLOBAL_H__


ThreadMgr.h

#ifndef	__THREADMGR_H__
#define	__THREADMGR_H__

#include "global.h"

class ThreadMgr
{
public:
	ThreadMgr(void);
	~ThreadMgr();
	bool Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTaskse);	
	bool AddTask(Task* task);	
	
	int GetTaskNum() {return m_TaskNum;}
	int GetThreadNum() 	{return m_ThreadNum;}
	int GetBusyNum() {return m_BusyNum;}
	
private:
	class Worker
	{
	public:
		Worker(ThreadMgr * pThreadMgr, Task* ptask = NULL);
		~Worker();
	
		void Start();
		void Terminate();
		pthread_t m_id;
		bool m_bwRun;
	
	private:
		static void* CallBack(void*);
	
        ThreadMgr * m_pThreadMgr;  
        Task * m_pTask;
	};
	
    unsigned int m_minThreads;  // 最少线程
    unsigned int m_maxThreads;  // 最多线程
    unsigned int m_maxPendingTasks;	// 创建新线程阀值
	bool m_bRun;	// 运行标志
	bool m_bEnableInsertTask;	// 可放任务标志
	
	int m_TaskNum;	// 待执行任务数量
	int m_ThreadNum;	// 总线程数量
	int m_BusyNum;	// 忙线程数量	
	
	typedef set<Worker *> THREADPOOL;  
	typedef list<Task *> TASKS;  
	typedef TASKS::iterator TasksItr;  
	typedef THREADPOOL::iterator ThreadPoolItr;  
  
	THREADPOOL m_BusyThreadPool;  
	THREADPOOL m_IdleThreadPool;  
	THREADPOOL m_TrashThreads;
    TASKS m_Tasks;  
	
	pthread_mutex_t m_ThreadMutex;
	pthread_mutex_t m_TaskMutex;
	
	pthread_cond_t m_TaskCond;
	
    Task * GetTask(); 
	void TerminateAll();
	bool MoveToIdlePool(Worker* worker);
	bool MoveToBusyPool(Worker* worker);
};

#endif	//__THREADMGR_H__


ThreadMgr.cpp

#include "ThreadMgr.h"

ThreadMgr::Worker::Worker(ThreadMgr * pThreadMgr, Task* ptask):
m_pThreadMgr(pThreadMgr), 
m_pTask(ptask), 
m_bwRun(true)
{
	pthread_create(&m_id, NULL, CallBack, (void*)this);
}

ThreadMgr::Worker::~Worker()
{
}

void* ThreadMgr::Worker::CallBack(void* pv)
{
	Worker* work = NULL;
	if (pv != NULL)
		work = (Worker*)pv;
	work->Start();
	return (void*)0;
}

void ThreadMgr::Worker::Terminate()
{
	m_bwRun = false;
	
	//pthread_exit(0);
	pthread_join(m_id, NULL);
}

/** 
  执行任务的工作线程
**/  
void ThreadMgr::Worker::Start()  
{  
    Task * pTask = NULL;  
    while(m_bwRun)  
    {
		if (m_pThreadMgr->m_bRun == false)	// 退出标记
			break;
        if(NULL == m_pTask)  
        {  
            pTask = m_pThreadMgr->GetTask();  
        }  
        else  
        {  
            pTask = m_pTask;  
            m_pTask = NULL;  
        }  
  
        if(NULL == pTask)  // 没有任务
        {
			pthread_mutex_lock(&(m_pThreadMgr->m_ThreadMutex));
			// 当前总线程数量多于最小线程数量阀值   将自己放进垃圾池,总线程数减一
            if(m_pThreadMgr->m_ThreadNum > m_pThreadMgr->m_minThreads)  
            {
                ThreadPoolItr itr = m_pThreadMgr->m_IdleThreadPool.find(this);  
                if(itr != m_pThreadMgr->m_IdleThreadPool.end())  
                {  
                    m_pThreadMgr->m_IdleThreadPool.erase(itr);
					m_pThreadMgr->m_ThreadNum--;
                    m_pThreadMgr->m_TrashThreads.insert(this);
                }
                m_bwRun = false;  
            }
			// 清理垃圾池, 然后等待执行任务信号
            else 
            {  
                ThreadPoolItr itr = m_pThreadMgr->m_TrashThreads.begin();  
                while(itr != m_pThreadMgr->m_TrashThreads.end())  
                {
					(*itr)->Terminate();
                    delete (*itr);  
                    m_pThreadMgr->m_TrashThreads.erase(itr);  
                    itr = m_pThreadMgr->m_TrashThreads.begin();  
                }
				cout << " wait signal " << endl;
				pthread_cond_wait(&(m_pThreadMgr->m_TaskCond), &(m_pThreadMgr->m_ThreadMutex));
				cout << this->m_id << " get signal " << endl;
            }
			pthread_mutex_unlock(&(m_pThreadMgr->m_ThreadMutex));
            continue;  
        }  
        else  
		if (pTask != NULL)
        {
			m_pThreadMgr->MoveToBusyPool(this);
            pTask->Run();
			m_pThreadMgr->MoveToIdlePool(this);
			delete pTask;
            pTask = NULL;
        }  
    }  
}  

ThreadMgr::ThreadMgr():m_bRun(false), m_bEnableInsertTask(false)
{
	m_ThreadMutex = PTHREAD_MUTEX_INITIALIZER;
	m_TaskMutex = PTHREAD_MUTEX_INITIALIZER;
	
	m_TaskCond = PTHREAD_COND_INITIALIZER;
}

ThreadMgr::~ThreadMgr()
{
	TerminateAll();
	pthread_mutex_destroy(&m_ThreadMutex);
	pthread_mutex_destroy(&m_TaskMutex);
	pthread_cond_destroy(&m_TaskCond);
}

/**
	初始化
**/
bool ThreadMgr::Init(unsigned int minThreads, unsigned int maxThreads, unsigned int maxPendingTasks)
{	if (minThreads == 0 || maxThreads == 0 || maxPendingTasks <= 0)
		return false;
	if (minThreads < 5) minThreads = 5;		// 最小线程阀值
	if (maxThreads < 10) maxThreads = 10;	// 最大线程阀值
	m_ThreadNum = 0;	// 总线程数量
	m_TaskNum = 0;		// 还未取走的任务数量
	m_BusyNum = 0;		// 忙碌线程数量
    m_minThreads = minThreads;  
    m_maxThreads = maxThreads;  
    m_maxPendingTasks = maxPendingTasks;  	// 创建新线程阀值
    unsigned int i = m_IdleThreadPool.size(); 
    for(; i<minThreads; i++)
	{
		Worker* pWorker = new Worker(this);
		m_IdleThreadPool.insert(pWorker);
		++m_ThreadNum;
	}
	m_bRun = true;
	m_bEnableInsertTask = true;
	//cout << " Init end " << endl;
}

 /**
	从任务列表中取出一个任务
 **/
Task * ThreadMgr::GetTask()  
{  
    Task * ptask = NULL;   
    pthread_mutex_lock(&m_TaskMutex);  
    if(m_TaskNum > 0)  
    {  
        ptask = m_Tasks.front();  
		if (ptask != NULL)
		{
			m_TaskNum--;
			m_Tasks.pop_front();  
		}			
    }
    pthread_mutex_unlock(&m_TaskMutex);  
    return ptask;  
} 
/** 
	如果当前任务大于最大等待任务,查看线程是否达到最大线程数量,没达到则创建新线程
    **/  
bool ThreadMgr::AddTask(Task* task)
{
    pthread_mutex_lock(&m_TaskMutex);  
	bool bsendSignal = false;
	if (m_TaskNum == 0)
		bsendSignal = true;
    if(!m_bEnableInsertTask)  
    {  
        return false;  
    }  
    if(NULL == task)  
    {  
        return false;  
    }
	// 任务数量大于最大等待数量
    if(m_TaskNum >= m_maxPendingTasks)  
    {  
        if(m_ThreadNum < m_maxThreads)	// 当前总线程少于最大线程数量  创建新线程
        {
            Worker * pWorker = new Worker(this, task);
			//cout << " Create New Thread " << m_ThreadNum << ',' << m_BusyNum << endl;
            if(NULL == pWorker)	// 创建新线程失败,把任务放进队列,
            {  
				m_Tasks.push_back(task);  
				++m_TaskNum;
				pthread_mutex_unlock(&m_TaskMutex);  
                return true;  
            }
			else	// 创建新线程成功
			{
				pthread_mutex_lock(&m_ThreadMutex);
				m_BusyThreadPool.insert(pWorker);
				++m_ThreadNum;
				pthread_mutex_unlock(&m_ThreadMutex); 
				pthread_mutex_unlock(&m_TaskMutex);  
			}
        }  
        else	// 当前线程等于或超过最大线程数量
        {
			m_Tasks.push_back(task);  
			++m_TaskNum;
			pthread_mutex_unlock(&m_TaskMutex);  
            return true;  
        } 
    }  
    else
    {  
        m_Tasks.push_back(task); 
		++m_TaskNum;
		if (bsendSignal)
			pthread_cond_signal(&m_TaskCond);
        pthread_mutex_unlock(&m_TaskMutex);   
    }  
    return true; 
}

/**
	将指定线程放到空闲池
**/
bool ThreadMgr::MoveToIdlePool(Worker* worker)
{
	pthread_mutex_lock(&m_ThreadMutex);
	ThreadPoolItr it = m_BusyThreadPool.find(worker);
	if (it != m_BusyThreadPool.end())
	{
		m_BusyThreadPool.erase(it);
		m_IdleThreadPool.insert(worker);
		m_BusyNum--;
		pthread_mutex_unlock(&m_ThreadMutex);
		return true;
	}
	pthread_mutex_unlock(&m_ThreadMutex);
	return false;
}

/**
	将指定线程放到忙碌池
**/
bool ThreadMgr::MoveToBusyPool(Worker* worker)
{
	pthread_mutex_lock(&m_ThreadMutex);
	ThreadPoolItr it = m_IdleThreadPool.find(worker);
	if (it != m_IdleThreadPool.end())
	{
		m_IdleThreadPool.erase(it);
		m_BusyThreadPool.insert(worker);
		m_BusyNum++;
		pthread_mutex_unlock(&m_ThreadMutex);
		return true;
	}
	pthread_mutex_unlock(&m_ThreadMutex);
	return false;
}

/**
	结束所有线程,只需要清理空闲池,垃圾池被任务执行完后的第一个wait线程清理掉
**/
void ThreadMgr::TerminateAll()
{
	//cout << " Terminate All " << endl;
	m_bEnableInsertTask = false;  // 不允许再放任务进来
    while(m_TaskNum > 0)  // 还有任务,等待任务执行完
    {  
        sleep(1);  
    }  
    m_bRun = false;  // 退出标记
    m_minThreads = 0;  
    m_maxThreads = 0;  
    m_maxPendingTasks = 0;  
    while(m_BusyNum > 0)  // 还有忙碌线程,等待执行结束
    {
		//cout << " Busy : " << m_BusyNum << endl;
        sleep(1);  
    }
	
	pthread_cond_broadcast(&m_TaskCond);	// 唤醒所有睡眠线程,此时的task必然都为NULL,而且退出标记为true,所有线程都会退出无限循环
	
	ThreadPoolItr it = m_IdleThreadPool.begin();
	for (; it != m_IdleThreadPool.end(); ++it)
	{
		pthread_join((*it)->m_id, NULL);
		//cout << (*it)->m_id << "  terminated !" << endl;
	}
	for (it = m_IdleThreadPool.begin(); it != m_IdleThreadPool.end();)
	{
		delete (*it);
		m_IdleThreadPool.erase(it);
		it = m_IdleThreadPool.begin();
	}
}



测试main.cpp

#include "global.h"
#include "ThreadMgr.h"

class MT : public Task
{
public:
	MT(int num):m_num(num){}
	int m_num;
	void Run()
	{
		cout << " [" << m_num << ']';
	}
};

int main(void)
{
	ThreadMgr* pMgr = new ThreadMgr;
	pMgr->Init(5, 10, 50);
	for (int i=0; i<6000000; ++i)
	{
		MT *pm = new MT(i);
		pMgr->AddTask(pm);
	}
	delete pMgr;
	pMgr = NULL;
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值