消息队列是线程间通信比较常用得方式,常用于解决经典模型生产者——消费者模型线程间得通信。

本文将结束基于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++ 九阴真经之线程间通信(消息队列)相关推荐

  1. 消息队列用于线程间通信

    我们知道,消息队列是进程间通信的方法之一, 当然,消息队列也可以用于线程间通信. 进程间通信的时候,我们需要使用ftok()函数创建同一个key值,(当然,进程间通信,key值我们可以自定义同一个值, ...

  2. Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001

    Disruptor本地线程队列_实现线程间通信---线程间通信工作笔记001 看到同事用这个东西了,这个挺好用的说是,可以实现,本地线程间的通信,好像在c++和java中都可以用 现在没时间研究啊,暂 ...

  3. 【Android】线程间通信——Handler消息机制

    文章目录 引言 Java层 永动机跑起来 示例 Looper Handler MessageQueue 永动机停下 Native层 nativeInit() nativePollOnce() nati ...

  4. (27)System Verilog多个线程间通信(队列)

    (27)System Verilog多个线程间通信(队列) 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog多个线程间通信(队列) 5) ...

  5. 线程间通信的三种方法 (转)

    http://www.cnblogs.com/puxidun/archive/2009/12/06/1618142.html 线程间通信的三种方法 多线程通信的方法主要有以下三种:  1.全局变量 进 ...

  6. android线程间通信的几种方法_Android 技能图谱学习路线

    Java基础 Java Object类方法 HashMap原理,Hash冲突,并发集合,线程安全集合及实现原理 HashMap 和 HashTable 区别 HashCode 作用,如何重载hashC ...

  7. linux线程间通信优点,进程间通信与线程间通信【转】

    一个进程写管道:写入字节数小于PIPE_BUF是原子操作,写操作在管道缓冲区没有及时读走时发生阻塞. 一个进程读管道:读操作在管道缓冲区没有数据时发生阻塞. 以前一直想找个机会总结一下进程和线程的通信 ...

  8. Java多线程编程-(4)-线程间通信机制的介绍与使用

    上一篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-线程本地Th ...

  9. 线程间通信: Handler , Looper, MessageQueue, Message (完结)

    概述:    为了 线程间 通信方便, Handler 机制 通过 Handler 和 Looper, MessageQueue, Message 这些 类 之间的协作, 简化 多线程的开发.  线程 ...

最新文章

  1. ViewBag、ViewData和TempData使用方法、区别与联系
  2. 对时域连续信号用matlab离散,数字信号处理上机实验一 离散时间信号的时域分析...
  3. 你知道面试必问的AOP吗,跟Java初学者分享几点经验
  4. XCode5 真机调试及发布应用
  5. Java-Super
  6. 孙丕恕:应把云计算大数据融在一起 降低社会运营成本
  7. Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
  8. php 扩展 返回字符串,PHP扩展函数返回字符串一定需要使用spprintf吗?
  9. Thread.Sleep太久,界面卡死
  10. Android Okhttp 配置HTTPS
  11. cplex java_线性最优解java实现+Cplex java调用
  12. linux c如何判断字符串是否为空
  13. Airtest微信朋友圈自动点赞
  14. 奔波真是辛苦啊,然而生命终将逝去,只希望当一切都结束的时候,能够没有遗憾吧。
  15. 计算机操作校本培训教材,小学教师校本培训教材.doc
  16. rk3399性能_(三)感知与大脑——5.机器人大脑嵌入式主板性能对比
  17. python统计分析方法
  18. Java的JDK和JRE
  19. 基于matlab各滤波器源代码,基于matlab各滤波器源代码
  20. python 利用cartopy绘制世界地图中部分地区的风场的流线形式

热门文章

  1. ADAS 通常包含的系统
  2. 计算机常用控温算法,常用温度控制方法原理
  3. tekla画圆球_用XSTEEL做空心球
  4. java向cdn_域名解析和cdn 原理
  5. 论文列表——EMNLP 2018
  6. 如何提升量化投研效率?来自辰钰投资的案例分享
  7. BAT脚本编写教程简单入门篇
  8. 设置CentOS防火墙开放端口
  9. 电脑开机后设置应用程序延时启动
  10. 【vue】vue2.x详解大全