C++ Linux IPC进程通信-消息队列MQ

原文链接:C++ Linux IPC进程通信-消息队列MQ

消息队列库<sys/msg.h>

相比于共享内存和管道,消息队列能够实现指定的消息格式和排序,能实现更复杂的通信

库函数

// 创建消息队列
int msgget(key_t, key, int msgflg);  
    return ID(成功) -1(错误)
    key为一个标记内存的关键字,可用自己指定,也可以用ftok函数转文件名为key,
    msgflg标志包括IPC_CREAT(创建)|IPC_EXCL(存在则报错)

//发送
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
    return 0(成功) -1(错误)  
    msgflg标志: IPC_NOWAIT(消息队列已经满了立即返回不阻塞),MSG_NOERROR(超过限制长度截断)
msg_ptr指向的对象是一个结构体:
struct msg{  
    long int message_type;  //队列需要的消息类别
    //其他需要通信的数据类型
};  

//接收
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg); 
    return 0(成功) -1(错误)  
    msgtype: >0接受指定类型数据 =0解释第一个数据 <0接受小于其绝对值类型的数据
    msgflg标志同样实现接收不阻塞和超长截断

// 控制
int msgctl(int msgid, int command, struct msgid_ds *buf);  
与共享内存的shmid_ds类似,对消息队列参数控制

实例:使用消息队列 子进程发送一个自增数据,父进程接收并输出


#include <iostream>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <cstring>

using namespace std;

template<typename T>
void check(const char* er, const T& a, const T& b) {
    if (a == b) {
        perror(er);
        exit(EXIT_FAILURE);
    }
}


struct Msg{
    long msg_type;
    int cnt;
};

int main()
{
    int fd=open("name_msg",O_CREAT|O_RDWR,0666);
    check(string("open").c_str(),fd,-1);
    key_t k=ftok("name_msg",'A');
    check(string("ftok").c_str(),k,-1);
    int ipcid=msgget(k,IPC_CREAT|0666);
    check(string("msgget").c_str(),ipcid,-1);
    
    Msg cntmsg;
    cntmsg.msg_type=1;
    cntmsg.cnt=0;
    
    pid_t cpid=fork();
    if(cpid==-1){
        check(string("fork").c_str(),cpid,-1);
    }else if(cpid>0){
        for(int i=0;i<3;i++){
            int r=msgrcv(ipcid,&cntmsg,sizeof(cntmsg),1,0);
            check(string("msgrcv").c_str(),r,-1);
            cout<<"parent get cnt="<<cntmsg.cnt<<"\n";
        }
    }else{
        for(int i=0;i<3;i++){
            cntmsg.cnt++;
            cout<<"child send cnt="<<cntmsg.cnt<<"\n";
            int r=msgsnd(ipcid,&cntmsg,sizeof(cntmsg),0);
            check(string("msgsnd").c_str(),r,-1);
        }
    }
    return 0;
}

特点(详细参考链接)

优点
  1. 解耦: 不用消息队列MQ,在多个连接条件下,主机需要维护每个进程的消息,增加主机的消耗. 采用消息队列,其他用户有需求可以直接从消息队列里自己获取.
  2. 异步: 当然消息队列存在实现了异步通信,不需要等待了.
  3. 缓冲: 对超量的请求使用MQ减小并发量,提高系统稳定性
缺点

MQ的复杂度较高,维护成本增加.如果MQ挂了,主服务直接挂了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aidroid

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值