用C++简单写的线程池

一、什么是线程池

  线程池就是被统一管理的若干个线程。这些线程在程序开始时就被创建,当程序需要另外一个线程执行代码时,就从线程池去取,不用每次都开辟线程。

二、线程池的优势

  1. 线程池可以控制开辟线程的数量,避免请求过多时创建的线程过多,造成线程阻塞。
  2. 提高响应速度,降低资源消耗。每次开辟线程和销毁都是资源消耗,线程池这个避免重复的创建和销毁线程。

三、代码实现


3.1 头文件定义

  下面定义了一个线程池的类,他大概一共有四部分成员参数组成:

  1. 任务队列
  2. 线程队列
  3. 线程池创建和销毁
  4. 公共锁和私有成员
/*
Datetime:2020/8/21
By LiuZhenguang
*/

#ifndef _THREADPOOL__H
#define _THREADPOOL__H
#include <vector>
#include <mutex>
#include <thread>
#include <deque>
#include <condition_variable>
#include <functional>

typedef std::function<void()> T_TASK;
typedef std::deque<T_TASK> T_TASK_QUEUE;
typedef std::vector<std::thread*> T_THREAD_QUEUE;

class ThreadPool{
public:
	~ThreadPool();
	ThreadPool(int defSize=3);

	void stopThreadPool();
	void startThreadPool();
	bool bIsThreadPoolStart();
	bool bIsThreadPoolStart;

	T_TASK_QUEUE taskQueue;
	T_TASK getTaskFrmQueue();
	void addTask2Queue(const Task& t);

	void ThreadLoop();
	T_THREAD_QUEUE threadQueue;

private:
	int threadSize;
	ThreadPool(const ThreadPool& t);//private禁止拷贝构造函数被调用
	const ThreadPool operator=(const ThreadPool& t);

	std::mutex m_mutex;
	std::condition_variable m_cond;
};
#endif

3.2 源文件定义

#include "ThreadPool.h"
#include <iostream>

/**************************
*构造函数
***************************/
ThreadPool::ThreadPool(int defSize):threadSize(defSize),m_mutex(),m_cond(),bIsThreadPoolStart(false)
{
	threadSize=defSize;
	startThreadPool();
}

/**************************
*线程初始化并启动
***************************/
void ThreadPool::startThreadPool()
{
	this.bIsThreadPoolStart = true;
	this.threadQueue.reserve(threadSize);

	for (int i=0; i<threadSize; ++i)
	{
		//创建线程,传入线程函数。使用bind是因为必须使用对象的函数地址
		threadQueue.push_back(new std::thread(std::bind(&ThreadPool::ThreadLoop, this)));
	}
}

/**************************
*线程函数,一直尝试获取任务
***************************/
void ThreadPool:: ThreadLoop()
{
	while (bIsThreadPoolStart)
	{
		T_TASK task = getTaskFrmQueue();
		if (task){
			task();
		}
	}
}

/**************************
*取任务
***************************/
Task ThreadPool::getTaskFrmQueue()
{
	std::unique_lock<std::mutex> lock(m_mutex);
	while (taskQueue.empty() && bIsThreadPoolStart)
	{
		m_cond.wait(lock);//条件变量等待锁阻塞,等待addTask或析构时的notify all()
	}

	T_TASK task;
	if (!taskQueue.empty() && bIsThreadPoolStart)
	{
		task = taskQueue.front();
		taskQueue.pop_front();
		if (TaskQueueSize_ > 0)
		{
			m_cond.notify_one();
		}
	}
	return task;
}

/**************************
* 添加任务
***************************/
void ThreadPool:: addTask(const Task& t)
{
	std::unique_lock<std::mutex> lock(m_mutex);
	taskQueue.push_back(t);
	m_cond.notify_all();
}

/**************************
* 析构函数
***************************/
ThreadPool::~ThreadPool()
{
	stopThreadPool();
}

/**************************
* 关闭线程池
***************************/
void ThreadPool:: stopThreadPool()
{
	bIsThreadPoolStart = false;

	std::unique_lock<std::mutex>  m_lock(m_mutex);//获得任务队列锁,停止添加或取任务
	m_cond.notify_all();    //唤醒所有其他线程
	for (auto thread : threadQueue)
	{
		thread->join();//主线程等待所有子线程结束
		delete thread;
	}
	threadQueue.clear();
}

问题

1、取任务也没有为那个任务分配线程、看着是主线程在取任务并执行
2、std::bind()机制链接
3、std::function()链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值