美文网首页
System V IPC:消息队列

System V IPC:消息队列

作者: FakeCSer爱去网吧 | 来源:发表于2020-02-26 21:02 被阅读0次

    概念

    • 底层是一个链队列
    • 与共享内存的不同是:内核要保证消息队列的FIFO性质,因此当有多个接收方进程接收消息队列中的消息的时候,不会产生冲突,由内核来协调他们的执行顺序。由于队列性质,队尾写,队头读,所以读写也不会存在冲突。

    API和涉及的数据结构

    创建消息队列
    #include <sys/msg.h>
    int msgget(key_t key,int flag);
    

    参数和返回值类比共享内存shmget

    发送消息
    #include <sys/msg.h>
    int msgsnd(int msqid,void * ptr,size_t nbytes,int flag);
    

    参数表:
    msqid:消息队列ID
    ptr:指向待发送的消息的指针
    nbytes:消息的大小
    flag:当消息队列满时如何处理(IPC_NOWAIT?)
    返回值:
    0:成功
    -1:失败

    • 消息结构体:
      msgsnd结构体中的ptr指向要发送的信息,此信息是一个结构体,需要用户自己定义,但是必须包含消息类型和消息的内容,例如下
    struct mymsg
    {
      long msgtype;
      char msgtext[MAXLENTH];
    }
    
    接收信息
    #include <sys/msg.h>
    int msgrcv(int msqid,void * ptr,size_t nbytes,long type,int flag);
    

    参数表:
    msqid:消息队列ID
    ptr:指向待发送的消息的指针
    nbytes:消息的大小
    type:消息类型
    flag:当消息队列满时如何处理(NOWAIT?)
    返回值:
    大于0:消息中数据部分的长度
    -1:失败

    • 消息类型的用法

    type = 0时,返回队列中的第一个消息
    type > 0时,返回队列中消息类型为type的第一个消息
    type < 0时,返回消息队列中类型值小于或等于type的消息,若有多个,则返回最小的

    注意数据大小要满足:消息队列定义的消息信息大小>=msgrcv中的数据大小>=msgsnd中的数据大小(即MAXLENTH>=msgrcv中nbytes>=msgsnd中的nbytes

    消息队列操作
    #include <sys/msg.h>
    int msg(int msqid,int cmd,struct msqid_ds * buf);
    

    参数表:
    msqid:消息队列ID
    cmd:待执行的操作
    buf:存放消息队列属性的内存地址
    返回值:
    0:成功
    -1:失败

    示例代码

    写端:创建消息队列,发送消息

    #include <sys/msg.h>
    #include <iostream>
    #include <unistd.h>
    #include <cstring>
    #include <sys/ipc.h>
    using namespace std;
    
    #define MAXLENTH 128
    
    struct msg_st
    {
        int msg_type;
        char msg_text[MAXLENTH];
    };
    
    int main()
    {
    
        int msg_id;
        int key = ftok(".",512);
        char buf[10];
    
        struct msg_st sndMsg;
        sndMsg.msg_type = 1;
    
        msg_id = msgget(key,IPC_CREAT|0666);
        if(msg_id == -1)
        {
            perror("msgget");
            exit(EXIT_FAILURE);
        }
    
        cin >> buf;
        strcpy(sndMsg.msg_text,buf);
    
        if(msgsnd(msg_id,(void *)&sndMsg,10,0)==-1)
        {
            perror("msgsnd");
            exit(EXIT_FAILURE);
        }
        sleep(10);
        return 0;
    }
    
    

    读端:接收信息,删除消息队列

    #include <sys/msg.h>
    #include <iostream>
    #include <sys/ipc.h>
    #include <cstring>
    using namespace std;
    
    #define MAXLENTH 128
    
    struct msg_st
    {
        int msg_type;
        char msg_text[MAXLENTH];
    };
    
    int main()
    {
    
        int msg_id;
        int key = ftok(".",512);
        char buf[100];
    
        struct msg_st rcvMsg;
    
        msg_id = msgget(key,0666);
        if(msg_id == -1)
        {
            perror("msgget");
            exit(EXIT_FAILURE);
        }
    
        if(msgrcv(msg_id,(void *)&rcvMsg,20,0,0)==-1)
        {
            perror("msgrcv");
            exit(EXIT_FAILURE);
        }
        cout <<rcvMsg.msg_text <<endl;
        msgctl(msg_id,IPC_RMID,0);
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:System V IPC:消息队列

          本文链接:https://www.haomeiwen.com/subject/ntlwchtx.html