自学内容网 自学内容网

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挂了,主服务直接挂了.


原文地址:https://blog.csdn.net/qq_58539881/article/details/142445277

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!