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++ 并发消息队列的更多相关文章

  1. Java高并发--消息队列

    Java高并发--消息队列 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 举个例子:在购物商城下单后,希望购买者能收到短信或者邮件通知.有一种做法时在下单逻辑执行后调 ...

  2. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

  3. 分布式消息队列XXL-MQ

    <分布式消息队列XXL-MQ>     一.简介 1.1 概述 XXL-MQ是一款轻量级分布式消息队列,支持串行.并行和广播等多种消息模型.现已开放源代码,开箱即用. 支持三种消息模式: ...

  4. threading模块和queue模块实现程序并发功能和消息队列

    简介: 通过三个例子熟悉一下python threading模块和queue模块实现程序并发功能和消息队列. 说明:以下实验基于python2.6 基本概念 什么是进程? 拥有独立的地址空间,内存,数 ...

  5. PHP结合memcacheq消息队列解决并发问题

    在处理业务逻辑时有可能遇到高并发问题,例如商城秒杀.微博评论等.如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?队列是个不错的选择.队列(Queue)又称先进先出(First In F ...

  6. Python并发编程之消息队列补充及如何创建线程池(六)

    大家好,并发编程 进入第六篇. 在第四章,讲消息通信时,我们学到了Queue消息队列的一些基本使用.昨天我在准备如何创建线程池这一章节的时候,发现对Queue消息队列的讲解有一些遗漏的知识点,而这些知 ...

  7. 高并发架构系列:MQ消息队列的12点核心原理总结

    消息队列已经逐渐成为分布式应用场景.内部通信.以及秒杀等高并发业务场景的核心手段,它具有低耦合.可靠投递.广播.流量控制.最终一致性 等一系列功能. 无论是 RabbitMQ.RocketMQ.Act ...

  8. Java并发编程原理与实战三十六:阻塞队列&消息队列

    一.阻塞队列 1.阻塞队列BlockingQueue ---->可以理解成生产者消费者的模式---->消费者要等待到生产者生产出来产品.---->而非阻塞队列ConcurrentLi ...

  9. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

随机推荐

  1. mac 找文件

    如何找到 etc 方法1: ! D# D! s2 F" f 七度苹果电脑软件1.打开Finder,按快键盘 Command + Shift + G,即可调出 前往文件夹 ,也可以左上角 找到 ...

  2. mysql 索引长度限制

    MyISAM存储引擎引键的长度综合不能超过1000字节 InnoDB单列索引长度不能超过767bytes,联合索引还有一个限制是3072

  3. 第四章 CSS基础

    1.CSS是cascading style sheets 层叠样式表.样式定义如何显示html元素,通常存储在样式表中,将样式添加到html中,是为了解决内容与表现分离的问题. 2.外部样式表可以极大 ...

  4. bzoj 2730: [HNOI2012]矿场搭建

    #include<cstdio> #include<cstring> #include<iostream> #define M 508 using namespac ...

  5. HDU 2795 单点更新,区间优先查找(想法)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. 在Linux中查看文件的编码及对文件进行编码转换

    如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8.下面介绍一下,在Li ...

  7. DatagridView的CellLeave光标离开响应事件,实现某列数字自动求和

    //光标离开DatagridView,循环获取DatagridView的每一行的第3列的值,相加传给重量 private void dgpz_dataGridView_CellLeave(object ...

  8. 3.5电子书pc显示

    使用svgalib 下载地址:https://launchpad.net/ubuntu/+source/svgalib/1:1.4.3-30svgalib_1.4.3.orig.tar.gzsvgal ...

  9. 加强版for循环

    /*加强版for循环 * 5.0以后有加强版for循环 * for(String name:nameArray){} * 1.String name:声明会带有数组单一元素的循环变量 *   数组元素 ...

  10. Android-Java第一课 内部类 (inner Class)

    总所周知,Android系统基于Linux,内核和驱动都是使用C/C++语言做开发,但应用层一般使用 JAVA 语言开发.今天我们就来学习一下java的内部类. 内部类: 是一个编译时的概念,一旦编译 ...