← 返回首页
Linux高级程序设计(六十二)
发表时间:2021-12-19 13:25:51
接收消息

1.msgrcv函数

msgrcv函数从标识符为 msqid 的消息队列中接收一个消息。一旦接收消息成功,则消息在消息队列中被删除。

#include <sys/msg.h>

ssize_t msgrcv( int msqid, void *msgp,  size_t msgsz, long msgtyp, int msgflg );

参数: - msqid:消息队列的标识符,代表要从哪个消息列中获取消息。 - msgp: 存放消息结构体的地址。 - msgsz:消息正文的字节数。 - msgtyp:消息的类型。可以有以下几种类型: msgtyp = 0:返回队列中的第一个消息。 msgtyp > 0:返回队列中消息类型为 msgtyp 的消息(常用)。 msgtyp < 0:返回队列中消息类型值小于或等于 msgtyp 绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。

注意:在获取某类型消息的时候,若队列中有多条此类型的消息,则获取最先添加的消息,即先进先出原则。

返回值: 成功:读取消息的长度 失败:-1

2.实例

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

#define N 128
typedef struct _msg  
{  
    long mtype;      // 消息类型  
    char mtext[N]; // 消息正文  
    //...         // 消息的正文可以有多个成员  
}MSG; 

//定义消息体长度
#define MSG_SIZE (sizeof(MSG)-sizeof(long))

int main(int argc, char *argv[])
{
    key_t key;
    int msgqid;

    key = ftok(".", 2021); // key 值
    if (key == -1)
    {
        perror("error to ftok:");
        exit(1);
    }

    // 创建消息队列
    msgqid = msgget(key, IPC_CREAT | 0666);
    if (msgqid == -1)
    {
        perror("error to create message queue:");
        exit(1);
    }

    printf("key=%#x\n",key);
    printf("msgqid=%d\n",msgqid);
    system("ipcs -q");

    MSG msg1 = {1,"hello,world!"};
    MSG msg2 = {2,"hello,ketty!"};
    MSG msg3 = {3,"hello,linux!"};
    MSG msg4 = {4,"hello,java!"};

    if(msgsnd(msgqid,&msg1,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg2,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg3,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg4,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    MSG rcv_msg;
    //获取第一个消息。
    if(msgrcv(msgqid,&rcv_msg,MSG_SIZE,0,0)==-1){
        perror("error to receive msg:");
        exit(1);
    }

    printf("msg=%s\n",rcv_msg.mtext);
    //获取指定类型的消息 
    //如果接收不到指定类型的消息会发生阻塞。
    if(msgrcv(msgqid,&rcv_msg,MSG_SIZE,4,0)==-1){
        perror("error to receive msg:");
        exit(1);
    }
    printf("msg=%s\n",rcv_msg.mtext);


    system("ipcs -q");
    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
key=0xe5010131
msgqid=131072

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 131072     root       666        0            0           

msg=hello,world!
msg=hello,java!

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 131072     root       666        256          2