`

消息队列

 
阅读更多
msgget函数用于创建一个新的消息队列或访问一个已存在的消息队列

IPC_NOWAIT标志使得msgsend调用非阻塞:如果没有存放新消息的可用空间,该函数就马上返回.这个条件可能发生的情况包括:
1.在指定的队列中已有太多的字节
2.在系统范围存在太多的消息
如果这两个条件中有一个存在,而且IPC_NOWAIT标志已指定,msgsnd就返回一个EAGAIN错误.如果这两个条件中有一个存在,但是IPC_NOWAIT标志未指定,那么调用纯种被投入睡眠.直到:
1.具备存放新消息的空间
2.由msqid标识的消息队列从系统中删除(这种情况下返回一个EIDRM错误)
3.调用线程被某个捕获的信号反中断(这种情况下返回一个EINTR错误)

msgctl函数提供一个消息队列上的各种控制操作

http://dash1982.iteye.com/blog/296583

MsgQueue.h
#ifndef MSGQUEUE_H
#define MSGQUEUE_H

namespace Utility
{

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)

#define COMMON_MESSAGE 1

struct Message
{
    long msgType;
    int bufLen;
    int addr;//地址
    int reserved1;
    int reserved2;
};

//初始化消息队列
int initMessageQueue(const char* msgfile,int& msgId,int msgType);

//关闭消息队列
int closeMessageQueue(int& msgId);

//清空消息
void clearMessage(int key,int& msgId,int msgType);

//发送普通消息
int sendMessage(const Message &msg,int msgId);

}//end of namespace Utility

#endif // MSGQUEUE_H




MsgQueue.cpp
#include "MsgQueue.h"
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
using namespace std;

namespace Utility
{

/*
    清空消息
*/
void clearMessage(int key,int& msgId,int msgType)
{
    int ret = 0;
    msgId = msgget(key, 0660);
    if (msgId<0){
        return;
    }
    while (1)
    {
        if(msgType==COMMON_MESSAGE)
        {
            Message msg;
            bzero(&msg,sizeof(msg));
            ret=msgrcv(msgId, &msg, sizeof(msg), 0, IPC_NOWAIT);
            if(ret<0){
                break;
            }
        }
    }
}


/*
    初始化消息队列
*/
int initMessageQueue(const char* msgFile,int & msgId,int msgType)
{
    //删除文件,避免引起不必要的问题,不删除可能会造成msgsend时卡死或发送失败的现象
    unlink(msgFile);
    msgId = -1;
    int fid = open(msgFile, O_RDWR | O_CREAT, FILE_MODE);
    if(fid<0)
    {
        cout << "创建文件:" << msgFile << "失败!" << endl;
        return fid;
    }
    close(fid);

    int key = ftok(msgFile, 'a');
    if(key<0)
    {
        cout << "创建消息队列失败!" << endl;
        return key;
    }

    if((msgId = msgget(key, IPC_CREAT | IPC_EXCL | 0660))==-1)
    {
        clearMessage(key,msgId,msgType);
        if (msgId<0)
        {
            cout << "创建消息队列失败!" << strerror(errno) << endl;
            return msgId;
        }
    }
    cout << "初始化消息队列成功.msgFile:" << msgFile << ",msgId:" << msgId << endl;
    return 0;
}

/*
    关闭消息队列
*/
int closeMessageQueue(int& msgId)
{
    int tmpMsgId = msgId;
    int ret = msgctl(msgId, IPC_RMID, 0);
    if(ret<0){
        cout << "关闭消息队列失败" << endl;
    }else{
        cout << "关闭消息队列成功,msgId:" << tmpMsgId << endl;
    }
    return ret;
}

/*
    发送普通信息
*/
int sendMessage(const Message &msg,int msgId)
{
    int ret = msgsnd(msgId, &msg, sizeof(msg), IPC_NOWAIT);
    if(ret<0){
        cout << "向消息队列发送消息失败,msgId:" << msgId << endl;
    }else{
        cout << "向消息队列发送消息成功,msgId:" << msgId << ",长度:" << msg.bufLen << endl;
    }
    return ret;
}

}//end of namespace Utility






test
#include "MsgQueue.h"
#include <pthread.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <iostream>
using namespace std;
using namespace Utility;

int g_msgId = 0;

class A
{
public:
    int value;
};

void* testRecvMessage(void*)
{
    Message msg;//收数据的结构体
    char rcvbuf[100];
    bzero(rcvbuf,100);
    int ret = 0;
    while(true)
    {
        ret = msgrcv(g_msgId, &msg, sizeof(msg), 0, IPC_NOWAIT);
        if (-1 != ret)
        {
            if(msg.msgType==COMMON_MESSAGE)
            {
                A** a = (A**)(msg.addr);
                cout << "bufLen:" << msg.bufLen << ",value:" << (*a)->value << endl;
                delete *a;
                *a = NULL;
                msg.addr = 0;
            }
            break;
        }else
        {
            usleep(1000);
        }
    }
    pthread_detach(pthread_self());
    return 0;
}

int main()
{
    pthread_t pid;
    pthread_create(&pid,NULL,testRecvMessage,NULL);
    int msgType = COMMON_MESSAGE;
    initMessageQueue("/tmp/test1.msg",g_msgId,msgType);
    A* a = new A;
    a->value = 10;
    Message message;
    bzero(&message,sizeof(message));
    message.msgType = COMMON_MESSAGE;
    message.bufLen = sizeof(message);
    message.addr = (int)&a;
    sendMessage(message,g_msgId);
    sleep(5);
    closeMessageQueue(g_msgId);
}


初始化消息队列成功.msgFile:/tmp/test1.msg,msgId:32769
向消息队列发送消息成功,msgId:32769,长度:20
bufLen:20,value:10
关闭消息队列成功,msgId:32769
分享到:
评论

相关推荐

    C#消息队列,windows使用消息队列,Queue消息队列

    此文档是C#开发的消息队列系统,适用于消息队列入门与新手。 在Windows 7 上安装消息队列的步骤 打开“控制面板”。 单击“程序”,然后在“程序和功能”下, 单击“打开或关闭 Windows 功能”。 -或者-单击“经典...

    WebLogic数据库和消息队列的配置.doc

    WebLogic数据库和消息队列的配置 本文档将详细介绍WebLogic数据库和消息队列的配置方法,主要包括配置数据库连接池和数据源的步骤。 一、配置数据库连接池 在WebLogic中,数据库连接池是通过JDBC(Java Database ...

    C++ 跨平台 异步消息队列

    在IT领域,尤其是在多线程编程中,异步消息队列是一种常见的设计模式,用于实现高效、非阻塞的消息通信。本项目名为"C++ 跨平台 异步消息队列",显然它提供了一个用C++编写的跨平台解决方案,用于在不同线程间安全地...

    C#消息队列发送及接收

    在IT行业中,消息队列(Message Queue,MQ)是一种常用于分布式系统中解耦组件、提高系统可扩展性和可靠性的技术。在C#编程中,我们可以利用Microsoft Message Queuing(MSMQ)库来实现消息队列的发送和接收。本文将...

    tp5.1消息队列 think-queue

    标题 "tp5.1消息队列 think-queue" 指的是使用ThinkPHP5.1框架集成的消息队列组件——think-queue。消息队列在软件开发中扮演着重要角色,它允许应用程序异步处理耗时任务,提高系统响应速度和整体性能。think-queue...

    ucOS消息队列使用

    ### ucOS消息队列使用详解 #### 一、配置ucOS消息队列 为了使用ucOS中的消息队列功能,首先需要对系统进行相应的配置。这些配置主要在`OS_CFG.H`头文件中完成。 ##### 配置项解析 1. **`OS_Q_EN`**: 定义是否启用...

    C# winform可忽略消息的自定义消息队列

    为了解决这个问题,我们可以采用自定义消息队列来优化处理流程,从而实现异步处理,避免UI线程被长时间占用。 标题中的“C# Winform可忽略消息的自定义消息队列”指的是创建一个特定的机制,允许在WinForm应用中,...

    基于网络编程中的消息队列

    消息队列是网络编程中的一种进程间通信(IPC,Inter-Process Communication)机制,它允许不同进程之间交换信息。在上述代码中,我们看到两个C程序:msgLucy.c 和 msgPeter.c,它们分别代表两个不同的进程,通过消息...

    各种消息队列对比

    消息队列是一种应用系统之间进行异步通信的中间件,它的核心功能是实现不同应用之间的信息传递,它在软件工程中常用于解耦服务、提高系统伸缩性以及保证消息传递的可靠性和顺序性。在当今分布式系统架构中,消息队列...

    用消息队列实现的简单聊天程序

    消息队列在IT行业中是一种非常重要的中间件技术,它主要用于应用程序间的异步通信,通过将消息放入消息队列,使得发送方和接收方无需同时在线即可完成数据交换,提高了系统的可扩展性和可靠性。在这个“用消息队列...

    linux使用消息队列实现进程间双向通信

    本文将深入探讨如何利用消息队列这一IPC机制实现进程间的双向通信。消息队列允许进程异步地发送和接收消息,提供了一种高效且灵活的数据交换方式。 消息队列是由内核管理的数据结构,它存储由进程发送的消息,并...

    linux c消息队列实现

    发送端读取指定的文件,并且按照环境变量中设置的消息队列键值进行发送。如果要改代码,只要把键值改一下,结构体储存要发送的消息的那个数组对应改成自己想发送的值,就可以很好的实现功能。接收端同样按环境变量...

    进程与消息队列进程与消息队列简单例子

    进程与消息队列进程通信 进程与消息队列是操作系统中两种基本的进程间通信方式。进程是指计算机系统中正在运行的程序实体,而消息队列则是一种特殊的数据结构,用于在进程之间传递数据。 进程 在操作系统中,进程...

    linux下进程间通信--消息队列

    其中,消息队列是一种高效且灵活的IPC机制,它允许进程将固定大小的消息发送到一个公共队列,其他进程可以从队列中读取这些消息。消息队列提供了异步通信的能力,并且支持消息的顺序处理,使得信息传递更加有序。 ...

    查看消息队列软件,消息队列工具

    消息队列软件是一种重要的中间件,它在分布式系统中扮演着关键角色,允许不同组件之间异步通信。这种工具能够帮助开发者有效地管理、监控和调试应用程序中的消息流动,提高系统的可扩展性和可靠性。本文将深入探讨...

    msmq.rar_java msmq_java 消息队列_java消息队列_msmq_消息队列

    在分布式系统中,消息队列扮演着至关重要的角色,因为它允许不同组件之间解耦,使得系统更加健壮和可扩展。本文将深入探讨Java如何与MSMQ进行交互,以及创建消息队列的详细步骤。 首先,我们需要理解消息队列的基本...

    消息队列应用.实现聊天

    根据给定文件的信息,我们可以提炼出以下关于“消息队列应用实现聊天”的相关知识点: ### 消息队列概述 消息队列(Message Queue)是一种应用程序间的通信模式,其中一个组件发送消息到另一个组件的消息队列中。...

    微服务SpringBoot整合Redis基于Redis的Stream消息队列实现异步秒杀下单

    【微服务SpringBoot整合Redis基于Redis的Stream消息队列实现异步秒杀下单】这篇文章主要讲解了如何在微服务架构中使用SpringBoot整合Redis来构建一个基于Redis Stream的消息队列,以此来实现实时、高效的异步秒杀...

    消息队列——message

    消息队列是操作系统提供的一种进程间通信(IPC)机制,主要用在多进程或多线程环境下,使得不同执行单元可以异步地交换信息。在Linux系统中,消息队列是一种可靠的存储数据的方式,它允许进程将数据结构作为消息发送...

    C++基于消息队列的多线程实现示例代码

    实现消息队列的关键因素是考量不同线程访问消息队列的同步问题。本实现涉及到几个知识点 std::lock_guard 介绍 std::lock_gurad 是 C++11 中定义的模板类。定义如下: template &lt;class&gt; class lock_guard; lock_...

Global site tag (gtag.js) - Google Analytics