博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
标准C++实现任务队列
阅读量:6367 次
发布时间:2019-06-23

本文共 2875 字,大约阅读时间需要 9 分钟。

hot3.png

下面介绍一个简单的任务队列,。

在实现任务队列前需要定义一个接口与一个工具类

  1. 任务接口:子类实现接口的run方法来处理具体任务。
  2. 自旋锁类:用于保护任务队列的并发访问(用C++11原子操作实现)。

任务接口源码如下

//任务接口class WorkItem{public:	//接口方法必须在子类实现	virtual void run() = 0;public:	//任务清理接口	virtual void clean()	{	}	//判断任务是否可执行(返回真时任务才会执行)	virtual bool runnable()	{		return true;	}};

自旋锁源码如下

//自旋锁类class SpinMutex{private:	atomic_flag flag = ATOMIC_FLAG_INIT;public:	void lock()	{		while (flag.test_and_set(memory_order_acquire));	}	void unlock()	{		flag.clear(std::memory_order_release);	}};

任务队列源码如下

//任务队列class AsyncExecQueue{private:	size_t maxsz;	size_t threads;	mutable SpinMutex mtx;	std::queue
> que; AsyncExecQueue() { this->maxsz = 0; } bool pop(shared_ptr
& item) { std::lock_guard
lk(mtx); if (que.empty()) return false; item = que.front(); que.pop(); return true; }public: //实现单例模式 static AsyncExecQueue* Instance() { static AsyncExecQueue obj; return &obj; }public: //中止任务处理 void stop() { threads = 0; } //清空队列 void clear() { std::lock_guard
lk(mtx); while (que.size() > 0) que.pop(); } //判断队列是否为空 bool empty() const { std::lock_guard
lk(mtx); return que.empty(); } //获取队列深度 size_t size() const { std::lock_guard
lk(mtx); return que.size(); } //获取任务线程线 size_t getThreads() const { return threads; } //任务对象入队 bool push(shared_ptr
item) { std::lock_guard
lk(mtx); if (maxsz > 0 && que.size() >= maxsz) return false; que.push(item); return true; } //启动任务队列(启动处理线程) void start(size_t threads = 4, size_t maxsz = 10000) { this->threads = threads; this->maxsz = maxsz; for (size_t i = 0; i < threads; i++) { std::thread(std::bind(&AsyncExecQueue::run, this)).detach(); } } public: //这个方法里面处理具体任务 void run() { shared_ptr
item; while (threads > 0) { if (pop(item)) { if (item->runnable()) { item->run(); item->clean(); } else { std::lock_guard
lk(mtx); que.push(item); } } else { std::chrono::milliseconds dura(1); std::this_thread::sleep_for(dura); } } }};

下面给出任务队列的测试代码

//实现一个任务接口class Task : public WorkItem{	string name;public:	//这个方法里面实现具体任务	void run()	{		cout << "异步处理任务[" << name << "]..." << endl;	}public:	Task(const string& name)	{		this->name = name;	}};int main(int argc, char** argv){	//使用智能指针	shared_ptr
A = make_shared
("A"); shared_ptr
B = make_shared
("B"); shared_ptr
C = make_shared
("C"); //启动任务队列 AsyncExecQueue::Instance()->start(); //将任务放入任务队列 AsyncExecQueue::Instance()->push(A); AsyncExecQueue::Instance()->push(B); AsyncExecQueue::Instance()->push(C); //等待所有任务执行完毕 while (AsyncExecQueue::Instance()->size() > 0) { std::chrono::milliseconds dura(1); std::this_thread::sleep_for(dura); } return 0;}

编译执行以下代码输出如下

异步处理任务[A]...异步处理任务[B]...异步处理任务[C]...

转载于:https://my.oschina.net/xungen/blog/3054570

你可能感兴趣的文章
所有转义字符
查看>>
C# 属性事件一些设置说明
查看>>
去除UITableViewheader footer黏性
查看>>
windows2003 iis6.0不能显示asp.net选项
查看>>
xen MacOS
查看>>
如何学好C和C++
查看>>
Gitlab通过custom_hooks自动更新服务器代码
查看>>
python 如何判断调用系统命令是否执行成功
查看>>
Lesson10 vSphere 管理特性
查看>>
memcache 扩展和 memcached扩展安装
查看>>
好程序员的查克拉---自信
查看>>
线程池的设计(二):领导者追随者线程池的设计
查看>>
获取设备列表
查看>>
Django使用网上模板做个能展示的博客
查看>>
基于同IP不同端口,同端口不同Ip的虚拟主机 基于FQDN的虚拟主机
查看>>
项目软件集成三方模块,编译中int32和uint32定义冲突解决方法
查看>>
StretchDIBits速度测试(HALFTONE)
查看>>
在.NET Workflo“.NET研究”w 3.5中使用多线程提高工作流性能
查看>>
验证Oracle处理速度
查看>>
自己写一个jquery
查看>>