C++ 九阴真经之线程间通信(消息队列)
消息队列是线程间通信比较常用得方式,常用于解决经典模型生产者——消费者模型线程间得通信。
本文将结束基于C++标准库实现得消息队列,可以支持任意参数类型,任务参数数量。
为了方便后续线程池、异步队列得实现,这里提取了公共基类。
class QueueObject : public noncopyable
{
public:QueueObject() :m_bStop(false), m_nCapacity(MAX_QUEUE_CAPACITY){}virtual ~QueueObject(){}void Stop(){m_bStop.store(true);m_condPop.notify_all(); // 唤醒所有线程执行}//设置最大容量void SetMaxCapacity(int nMax){m_nCapacity = nMax;}//获取队列任务数量virtual size_t GetTaskNum() = 0;bool IsStop(){return m_bStop;}protected:int m_nCapacity = 0; //队列最大容量std::condition_variable_any m_condPush; //写入条件量std::condition_variable_any m_condPop; //读取条件量std::mutex m_mu; //互斥锁 // 是否关闭提交std::atomic<bool> m_bStop;};
消息队列实现
template<typename T, typename... ARGS>
class CMsgQueue : public QueueObject
{
public:using QueueObject::QueueObject;void Push(T val, const ARGS... args){while (m_dataQueue.size() == m_nCapacity) //队列已满{m_condPush.wait(m_mu); //等待,将暂时的解锁}m_dataQueue.emplace(std::make_tuple(val, args...));m_condPop.notify_one(); // 唤醒一个线程执行}//批量获取参数值bool Pop(std::tuple<T, ARGS...>& value, int waitTime = -1){std::unique_lock<std::mutex> lock(m_mu);if (waitTime < 0){this->m_condPop.wait(lock,[this] {return !this->m_dataQueue.empty();}); // wait 直到有 task}else{auto status = m_condPop.wait_for(lock, std::chrono::seconds(waitTime), [this] {return !this->m_dataQueue.empty();});if (!status ){return false;}}value = std::move(this->m_dataQueue.front()); // 取一个 taskthis->m_dataQueue.pop();//通知写线程m_condPush.notify_one();return true;}bool Pop( T& value, ARGS&... args, int waitTime = -1){std::tuple<T,ARGS...> tupVal;if (Pop(tupVal, waitTime)){FetchParam<0>(tupVal, value, args...);return true;}return false;}template<int NUM, typename P, typename...PARMS>void FetchParam(std::tuple<T,ARGS...>& tupVal, P& p, PARMS&... params){p = std::get<NUM>(tupVal);FetchParam<NUM+1>(tupVal, params...);}template<int NUM, typename P>void FetchParam(std::tuple<T,ARGS...>& tupVal, P& p){p = std::get<NUM>(tupVal);} //获取队列任务数量virtual size_t GetTaskNum(){return m_dataQueue.size();}private:std::queue<std::tuple<T, ARGS...>> m_dataQueue;
};
测试:
int main()
{CMsgQueue<std::string, int, int> mq;mq.Push("test", 10,20);mq.Push("test2", 100,200);std::string val;int num1, num2;mq.Pop(val, num1, num2);std::cout << val << " " << num1 << " " << num2 << std::endl;mq.Pop( val, num1, num2);std::cout << val << " " << num1 << " " << num2 << std::endl;return 0;
}
C++ 九阴真经之线程间通信(消息队列)相关推荐
- 消息队列用于线程间通信
我们知道,消息队列是进程间通信的方法之一, 当然,消息队列也可以用于线程间通信. 进程间通信的时候,我们需要使用ftok()函数创建同一个key值,(当然,进程间通信,key值我们可以自定义同一个值, ...
- Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001
Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001 看到同事用这个东西了,这个挺好用的说是,可以实现,本地线程间的通信,好像在c++和java中都可以用 现在没时间研究啊,暂 ...
- 【Android】线程间通信——Handler消息机制
文章目录 引言 Java层 永动机跑起来 示例 Looper Handler MessageQueue 永动机停下 Native层 nativeInit() nativePollOnce() nati ...
- (27)System Verilog多个线程间通信(队列)
(27)System Verilog多个线程间通信(队列) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog多个线程间通信(队列) 5) ...
- 线程间通信的三种方法 (转)
http://www.cnblogs.com/puxidun/archive/2009/12/06/1618142.html 线程间通信的三种方法 多线程通信的方法主要有以下三种: 1.全局变量 进 ...
- android线程间通信的几种方法_Android 技能图谱学习路线
Java基础 Java Object类方法 HashMap原理,Hash冲突,并发集合,线程安全集合及实现原理 HashMap 和 HashTable 区别 HashCode 作用,如何重载hashC ...
- linux线程间通信优点,进程间通信与线程间通信【转】
一个进程写管道:写入字节数小于PIPE_BUF是原子操作,写操作在管道缓冲区没有及时读走时发生阻塞. 一个进程读管道:读操作在管道缓冲区没有数据时发生阻塞. 以前一直想找个机会总结一下进程和线程的通信 ...
- Java多线程编程-(4)-线程间通信机制的介绍与使用
上一篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地Th ...
- 线程间通信: Handler , Looper, MessageQueue, Message (完结)
概述: 为了 线程间 通信方便, Handler 机制 通过 Handler 和 Looper, MessageQueue, Message 这些 类 之间的协作, 简化 多线程的开发. 线程 ...
最新文章
- ViewBag、ViewData和TempData使用方法、区别与联系
- 对时域连续信号用matlab离散,数字信号处理上机实验一 离散时间信号的时域分析...
- 你知道面试必问的AOP吗,跟Java初学者分享几点经验
- XCode5 真机调试及发布应用
- Java-Super
- 孙丕恕:应把云计算大数据融在一起 降低社会运营成本
- Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
- php 扩展 返回字符串,PHP扩展函数返回字符串一定需要使用spprintf吗?
- Thread.Sleep太久,界面卡死
- Android Okhttp 配置HTTPS
- cplex java_线性最优解java实现+Cplex java调用
- linux c如何判断字符串是否为空
- Airtest微信朋友圈自动点赞
- 奔波真是辛苦啊,然而生命终将逝去,只希望当一切都结束的时候,能够没有遗憾吧。
- 计算机操作校本培训教材,小学教师校本培训教材.doc
- rk3399性能_(三)感知与大脑——5.机器人大脑嵌入式主板性能对比
- python统计分析方法
- Java的JDK和JRE
- 基于matlab各滤波器源代码,基于matlab各滤波器源代码
- python 利用cartopy绘制世界地图中部分地区的风场的流线形式