C++高并发服务器设计--线程池封装设计(七)

本文介绍了线程池的概念及其优点,如资源节省和响应速度提升,并展示了如何使用C++封装互斥量和条件变量。通过实例展示了如何创建和管理线程池,包括任务的添加、线程的创建和销毁。此外,还提供了任务类和测试用例,用于演示线程池的实际应用。
摘要由CSDN通过智能技术生成

线程池封装设计
1.什么是线程池
线程池就是管理线程的池子,当有任务要处理时,不用频繁创建新线程,而是从池子拿个线程出来处理。当任务执行完,线程并不会被销毁,而是在等待下一个任务。因此可以节省资源,提高响应速度。

你去餐厅吃饭,服务员总是提前洗好盘子,不会等你来打饭的时候才洗盘子,盘子就像是线程池里的线程,你打饭就是要处理的任务。

2、线程池的优点

  1. 降低资源消耗:通过重复利用现有的线程来执行任务,避免多次创建和销毁线程。
  2. 提高相应速度:因为省去了创建线程这个步骤,所以在拿到任务时,可以立刻开始执行。
  3. 提供附加功能:线程池的可拓展性使得我们可以自己加入新的功能,比如说定时、延时来执行某些线程。
    互斥量(mutex)封装
class CPThreadMutex
{
public:
	CPThreadMutex();
	~CPThreadMutex();
	bool lock();
	bool unlock();
	bool trylock();
protected:
	pthread_mutex_t m_mutex;
};
CPThreadMutex::CPThreadMutex()
{
	if(pthread_mutex_init(&m_mutex,NULL)!=0)
	{
		perror("pthread mutex init error");
	}
}

CPThreadMutex::~CPThreadMutex()
{
 	if(pthread_mutex_destroy(&m_mutex)!=0)
 	{
 		perror("pthread mutex destroy error");
 	}
}

bool CPThreadMutex::lock()
{
	int ret=pthread_mutex_lock(&m_mutex);
	if (ret !=0)
	{
		perror("pthread mutex lock error");
	}
	return ret==0 ? true: false;
}

bool CPThreadMutex::unlock()
{
	int ret=pthread_mutex_unlock(&m_mutex);
	if (ret !=0)
	{
		perror("pthread mutex unlock error");
	}
	return ret==0 ? true: false;
}

bool CPThreadMutex::trylock()
{
	int ret=pthread_mutex_trylock(&m_mutex);
	if (ret !=0)
	{
		perror("pthread mutex trylock error");
	}
	return ret==0 ? true: false;
}

条件变量(cond)封装

class CPThreadCond :public CPThreadMutex
{
public:
	CPThreadCond();
	~CPThreadCond();
	bool wait();
	bool timewait(unsigned int sec);
	bool signal();
	bool broadcast();
	bool isTimeout();
private:
	pthread_cond_t m_cond;
	bool m_btimeout;
};

```bash
CPThreadCond::CPThreadCond()
:CPThreadMutex(),m_btimeout(false)
{
	if(pthread_cond_init(&m_cond,NULL)!=0)
	{
		perror("pthread cond init error");
	}
}

CPThreadCond::~CPThreadCond()
{
	if(pthread_cond_destroy(&m_cond)!=0)
	{
		perror("pthread cond destroy error");
	}
}

bool CPThreadCond::wait()
{
	int ret=pthread_cond_wait(&m_cond,&m_mutex);
	if (ret !=0)
	{
		perror("pthread cond wait error");
	}
	return ret==0 ? true: false;
}

bool CPThreadCond::timewait(unsigned int sec) 
{
	struct timespec abstime;
	
	clock_gettime(CLOCK_REALTIME, &abstime);
	abstime.tv_sec += sec;
	m_btimeout=false;
	int ret=pthread_cond_timedwait(&m_cond,&m_mutex,&abstime);
	if (ret==ETIMEDOUT)
	{
		m_btimeout=true;
		return false;
	}
	else if (ret!=0)
	{
		perror("pthread cond timedwait error");
	}
	return ret==0 ? true: false;
}

bool CPThreadCond::signal()
{
	int ret=pthread_cond_signal(&m_cond);
	if (ret !=0)
	{
		perror("pthread cond signal error");
	}
	return ret==0 ? true: false;
}

bool CPThreadCond::broadcast()
{
	int ret=pthread_cond_broadcast(&m_cond);
	if (ret !=0)
	{
		perror("pthread cond broadcast error");
	}
	return ret==0 ? true: false;
}

bool CPThreadCond::isTimeout()
{
	return m_btimeout;
}

任务类定义

class CTask
{
public:
	CTask(){}
	~CTask(){}
	virtual int run()=0;
};

class CmyCTask:public CTask
{
public:
	CmyCTask(int id) {m_id = id;}
	int run()
	{
		printf("Begin task[%d] \n", m_id);
		sleep(3);
		printf("End task[%d] \n", m_id);
		return 0;
	}
	int m_id;	
protected:
	
};

线程池类设计

typedef queue<CTask *> queue_task;
class CThreadPool
{
public:
	CThreadPool(unsigned int max=100,unsigned int min=10,unsigned int timeout=60);
	~CThreadPool();
	void addTask(CTask *task);	// Add a new task.
	void createThread();		// Create a thread.
	void createThread(unsigned NumCreate);	// Create a num of thread
	void destroy();				// Destroy all threads
	
//private:
	static void *taskThread(void *arg);// work thread
	unsigned int m_maxcount;		// max thread
	unsigned int m_mincount; 		// min thread
	unsigned int m_count;	 		// current nums
	unsigned int m_idlecount; 		// idle thread nums
	unsigned int m_waitsec;			// timeout delay.
	queue_task	 m_taskQueue;
	CPThreadCond m_taskCond;
	CPThreadCond m_cond;
	bool m_bStop;
};
CThreadPool::CThreadPool(unsigned int max/* =100 */,unsigned int min/* =10 */,unsigned int timeout/* =60 */)
{
	m_bStop = false;
	m_maxcount = max;		// max thread
	m_mincount = min; 		// min thread
	m_count = 0;	 		// current nums
	m_idlecount = 0; 		// idle thread nums
	m_waitsec = timeout;	// timeout delay.
	
	// 创建最小数量的线程
	m_cond.lock();
	for(unsigned i = 0; i < m_mincount; i++)
	{
		createThread();
	}
	m_cond.unlock();
}

CThreadPool::~CThreadPool()
{
	destroy();
}

void CThreadPool::createThread()
{
	pthread_t tid;
	
	if(pthread_create(&tid, NULL, taskThread, this) != 0)
	{
		perror("pthread_create");
	}
	else
	{
		printf("thread[0x%x] create!!\n", (int)pthread_self());
		m_count++;
	}
}

void CThreadPool::createThread(unsigned NumCreate)
{
	// 创建最小数量的线程
	m_cond.lock();
	for(unsigned i = 0; i < NumCreate && (m_count < m_maxcount-2); i++)
	{
		createThread();
	}
	m_cond.unlock();
}

void CThreadPool::addTask(CTask *task)
{
	// 1. 添加到任务列表
	m_taskCond.lock();
	printf("Add task[%d]!\n", ((CmyCTask*)task)->m_id);
	m_taskQueue.push(task);
	m_taskCond.unlock();
	
	
	// 2. 通知线程处理
	m_cond.lock();
	if(m_idlecount > 0)
	{
		m_cond.signal();
	}
	else if(m_count < m_maxcount)
	{
		createThread(); //如果没有空闲线程则尝试再创建线程
	}
	m_cond.unlock();
}


// Work thread
void * CThreadPool::taskThread(void *arg)
{
	pthread_detach(pthread_self()); //设置为自动分离
	CThreadPool *pool = (CThreadPool*)arg;
	while(1)
	{
		//1. 取任务做任务
		pool->m_taskCond.lock();
		while(!pool->m_taskQueue.empty())
		{
			CTask *ptask = pool->m_taskQueue.front();
			pool->m_taskQueue.pop();
			pool->m_taskCond.unlock();
			
			// do task
			ptask->run();
			delete ptask;
			
			pool->m_taskCond.lock();
		}
		pool->m_taskCond.unlock();
		
		//2. 进入等待处理
		pool->m_cond.lock();
		if(pool->m_taskQueue.empty())
		{
			pool->m_idlecount++;
			bool bSignal = pool->m_cond.timewait(pool->m_waitsec);
			pool->m_idlecount--;
			
			// 判断是否退出或则超时,超时则判断如果超过最小个数的则进行销毁,
			// 如果是正常退出则判断是否任务做完了,做完了就销毁
			if(((!bSignal && pool->m_count > pool->m_mincount)
				|| pool->m_bStop) && pool->m_taskQueue.empty())
			{
				//清理线程
				pool->m_count--;
				pool->m_cond.unlock();			
				if(!bSignal)
					printf("thread[0x%x] timeout exit!!\n", (int)pthread_self());
				else
					printf("thread[0x%x] stop exit!!\n", (int)pthread_self());
				pthread_exit(NULL);	
			}
		}
		pool->m_cond.unlock();
	}
}

void CThreadPool::destroy()
{
	m_bStop = true;
	while(m_count)
	{
		m_cond.lock();
		m_cond.broadcast(); 
		m_cond.unlock();
		sleep(1);
	}
}

测试案例:

int main()
{
	int taskid = 0;
	CThreadPool pool(20, 5, 3);
	//pool.start(6);
	sleep(1);
	for(unsigned i = 0; i < 50; i++)
	{
		CmyCTask *tsk = new CmyCTask(taskid++);
		pool.addTask(tsk);
	}
	sleep(1);
	for(unsigned i = 0; i < 10; i++)
	{
		CmyCTask *tsk = new CmyCTask(taskid++);
		pool.addTask(tsk);
	}	
	
	sleep(20);
	for(unsigned i = 0; i < 50; i++)
	{
		CmyCTask *tsk = new CmyCTask(taskid++);
		pool.addTask(tsk);
	}	
}

测试结果
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C君莫笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值