使用 C++11 编写可复用多线程任务池

本文介绍了如何使用 C++11 标准来编写一个可复用的多线程任务池。任务池包括任务基类 Task,负责抽象工作接口;TaskQueue 用于管理任务的存储、删除和撤回;以及 ThreadPool 类,作为核心业务处理单元。文中提供了相关头文件和主程序的概览,并提及了参考的开源项目 OEasyPool。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类的功能

  • Task (任务基类)
    该类主要实现一个任务类
    virtual int doWork() = 0;

  • TaskQueue (任务队列)
    该类主要针对任务的存储、删除、撤回等状态做管理

  • ThreadPool (线程池)
    整个线程池的核心业务处理类

代码

  • Task.h
//任务的基类
#pragma once

#include <time.h>
#include <atomic>

//任务的基类
class Task
{
   
public:
	//构造、析构函数
	Task():_id(_nRequestID++),_isCancelRequired(false),_createTime(clock()){
   }
	~Task(){
   };

	// 任务类虚接口,继承这个类的必须要实现这个接口
	virtual int doWork(void) = 0;
	
	// 任务已取消回调
	virtual int onCanceled(void)
	{
   
		return  1;
	}
	// 任务已完成
	virtual int onCompleted(int)
	{
   
		return 1;
	}
	// 任务是否超时
	virtual bool isTimeout(const clock_t& now)
	{
   
		return ((now - _createTime) > 5000);
	}
	// 获取任务ID
	size_t getID(void)
	{
   
		return _id;
	}
	//获取任务取消状态
	bool isCancelRequired(void)
	{
   
		return _isCancelRequired;
	}
	//设置任务取消状态
	void setCancelRequired(void)
	{
   
		_isCancelRequired = true;
	}

	
	
protected:
	size_t _id;	//任务的唯一标识
	clock_t _createTime;	//任务创建时间,非Unix时间戳
	
private:
	static std::atomic<size_t> _nRequestID;
	std::atomic<bool> _isCancelRequired;	//任务取消状态
};

//selectany可以让我们在.h文件中初始化一个全局变量而不是只能放在.cpp中。
//这样的代码来初始化这个全局变量。既是该.h被多次include,链接器也会为我们剔除多重定义的错误。
__declspec(selectany) std::atomic<size_t> Task::_nRequestID = 100000;

  • TaskQueue.h
#pragma once

#include <deque>
#include <mutex>
#include <condition_variable>
#include <unordered_map>
#include <memory>
#include <thread>

//任务队列
template<typename T>
class TaskQueue
{
   
public:
	//向队列的末尾插入任务,task是任务类
	void put_back(std::shared_ptr<T>& task)
	{
   
		std::unique_lock<std::mutex> lock(_mutexQueue);
		_queue.push_back(task);
		_conditPut.notify_one();
	}
	
	//向队列的头部插入任务
	void put_front(std::shared_ptr<T>& task)
	{
   
		std::unique_lock<std::mutex> lock(_mutexQueue);
		_queue.push_front(task);
		_conditPut.notify_one();
	}
	
	//获取队首(并将任务加到运行任务列表中),返回tase是任务类
	std::shared_ptr<T> get(void) {
   
		std::unique_lock<std::mutex> lock(_mutexQueue);
		if (_queue.empty())
			return nullptr;
		//lock_guard取代了mutex的lock()和unlock();
		std::lock_guard<std::mutex> lock_doing_task(_mutexDoingTask);
		
		std::shared_ptr<T>& task = _queue.front();
		
		_mapDoingTask.insert(std::make_pair(task->getID(), task));
		
		_queue.pop_front();
		return task;
	}
	
	//获取双向链表queue的大小
	size_t size(void)
	{
   
		std::unique_lock<std::mutex> lock(_mutexQueue);
		return _queue.size();
	}
	
	//释放队列
	void release(void)
	{
   
		deleteAllTasks
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值