C++ 并发消息队列
C++ 并发消息队列
在网上找到了一份POSIX线程显示的并发消息队列示例代码:
http://codereview.stackexchange.com/questions/41604/thread-safe-concurrent-fifo-queue-in-c
上面的示例代码其实是有问题的,他只能对并发Push或者并发Pop进行上锁,二并不能保证同时Push和Pop是线程安全的,所以在锁队列时只能使用一个锁。同时该代码并不支持Windows,所以按照这篇文档的思路想使用标准模板库(STL)实现一份平台无关的代码,具体实现如下所示。
#include <queue>
#include <mutex>
#include <thread>
#include <chrono>
#include <memory>
#include <condition_variable> typedef struct task_tag
{
int data;
task_tag( int i ) : data(i) { }
} Task, *PTask; class MessageQueue
{
public:
MessageQueue(){}
~MessageQueue()
{
if ( !m_queue.empty() )
{
PTask pRtn = m_queue.front();
delete pRtn;
} } void PushTask( PTask pTask )
{
std::unique_lock<std::mutex> lock( m_queueMutex );
m_queue.push( pTask );
m_cond.notify_one();
} PTask PopTask()
{
PTask pRtn = NULL;
std::unique_lock<std::mutex> lock( m_queueMutex );
while ( m_queue.empty() )
{
m_cond.wait_for( lock, std::chrono::seconds() );
} if ( !m_queue.empty() )
{
pRtn = m_queue.front();
if ( pRtn->data != )
m_queue.pop();
} return pRtn;
} private:
std::mutex m_queueMutex;
std::condition_variable m_cond;
std::queue<PTask> m_queue;
}; void thread_fun( MessageQueue *arguments )
{
while ( true )
{
PTask data = arguments->PopTask(); if (data != NULL)
{
printf( "Thread is: %d\n", std::this_thread::get_id() );
printf(" %d\n", data->data );
if ( == data->data ) //Thread end.
break;
else
delete data;
}
} return;
} int main( int argc, char *argv[] )
{
MessageQueue cq; #define THREAD_NUM 3
std::thread threads[THREAD_NUM]; for ( int i=; i<THREAD_NUM; ++i )
threads[i] = std::thread( thread_fun, &cq ); int i = ;
while( i > )
{
Task *pTask = new Task( --i );
cq.PushTask( pTask );
} for ( int i=; i<THREAD_NUM; ++i)
threads[i].join(); //system( "pause" );
return ;
}
在示例代码中,我们使主线程向公共队列cq中Push任务,而其他的线程则负责取出任务并打印任务,由于std::cout并不支持并发线程安全,所以在打印任务时使用printf。主线程new出的任务,在其他线程中使用并销毁,当主线程发送data为0的任务时,则规定任务发送完毕,而其他的线程获取到data为0的任务后退出线程,data为0的任务则有消息队列负责销毁。整个消息队列使用标准模板库实现,现实跨平台。
在最初设计std::queue<PTask>的时候,想使用std::queue<std::shared_ptr<Task>>来管理主线程new出来的任务,这样智能指针则负责处理任务的销毁工作,但是在多线程并发的时候程序莫名的崩溃,仔细调试了半天,还是没有找到问题,最终我怀疑智能指针在多线程中是不是有问题呢?所以不得不放弃最初的设计。
C++ 并发消息队列的更多相关文章
- Java高并发--消息队列
Java高并发--消息队列 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 举个例子:在购物商城下单后,希望购买者能收到短信或者邮件通知.有一种做法时在下单逻辑执行后调 ...
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三 多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...
- 分布式消息队列XXL-MQ
<分布式消息队列XXL-MQ> 一.简介 1.1 概述 XXL-MQ是一款轻量级分布式消息队列,支持串行.并行和广播等多种消息模型.现已开放源代码,开箱即用. 支持三种消息模式: ...
- threading模块和queue模块实现程序并发功能和消息队列
简介: 通过三个例子熟悉一下python threading模块和queue模块实现程序并发功能和消息队列. 说明:以下实验基于python2.6 基本概念 什么是进程? 拥有独立的地址空间,内存,数 ...
- PHP结合memcacheq消息队列解决并发问题
在处理业务逻辑时有可能遇到高并发问题,例如商城秒杀.微博评论等.如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?队列是个不错的选择.队列(Queue)又称先进先出(First In F ...
- Python并发编程之消息队列补充及如何创建线程池(六)
大家好,并发编程 进入第六篇. 在第四章,讲消息通信时,我们学到了Queue消息队列的一些基本使用.昨天我在准备如何创建线程池这一章节的时候,发现对Queue消息队列的讲解有一些遗漏的知识点,而这些知 ...
- 高并发架构系列:MQ消息队列的12点核心原理总结
消息队列已经逐渐成为分布式应用场景.内部通信.以及秒杀等高并发业务场景的核心手段,它具有低耦合.可靠投递.广播.流量控制.最终一致性 等一系列功能. 无论是 RabbitMQ.RocketMQ.Act ...
- Java并发编程原理与实战三十六:阻塞队列&消息队列
一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...
- java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购
此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...
随机推荐
- XAML-1
1.XAML Extension Application Marked Language,是WPF技术中专门用来设计UI的语言.XAML是从XML派生出来的,是一种声明式语言,当你看到一个标签,就是声 ...
- SSH由WAS/Tomcat/Weblogic迁移到JBOSS
又是一个凌晨,又一次搞项目在新的中间件上的可部署性验证... 原来将项目部署到was7上,花了三个晚上到凌晨1点多的时间,总结出了只要将common-logging和wodenxx.jar两个jar包 ...
- 喜讯!Ubuntu 16.10(Yakkety Yak) Final Beta发布喽!!!
上月三十日,代号为"Yakkety Yak"的Ubuntu 16.10发行版本的Final Beta正式上线.Canonical的开发者Steve Langasek说道:" ...
- [Js]焦点图轮播效果
一.所用到的知识点 1.DOM操作 2.定时器 3.事件运用 4.Js动画 5.函数递归 6.无限滚动大法 二.结构和样式 <div id="banner" class=&q ...
- 优化MYSQL数据库的方法
1.选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置NOT NULL,例如'省份,性别',最好设置为ENUM2.使用连接(JOIN)来代替子查询: a.删除没有任何订单客户:DELETE ...
- Windows多线程编程总结
1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这种内存块是一个数据结构,表示内核对象的各种特征.并且只能由内核来访问.应用程序若需要访问内核对象,需要通过操作系统提供的函数来 ...
- linux下安装vtune_amplifier_xe_2015_update4
说明: linux系统: CentOS 6.0 Vtune版本: 2015 安装过程: 1.下载vtune_amplifier_xe_2015_update4.tar.gz(到官网去下载 ...
- C#生成唯一的ID保存到数据库
直接用.NET Framework 提供的 Guid() 函数: Guid.NewGuid()是指生成唯一码的规则 System.Guid.NewGuid().ToString()全球唯一标识符 (G ...
- mysql 启动错误1026
进入“事件查看器”“应用程序”果然发现很多MySql的错误Default storage engine (InnoDB) is not available 于是进入MySql的安装目录找到my.ini ...
- rpm软件包管理/yum软件管理
绝大数开源软件都是公布源代码的,源代码一般被打包为tar.gz归档压缩文件,然后手工编译为二进制可执行文件 ./configure 检查编译环境/相关库文件/配置参数,生成makefile make ...