Linux 编程。如何使用消息队列发送数组?

Linux programming. How to send array with message queue?

我有 writer.c 和 reader.c,我正在尝试从 writer 发送数组,然后在 reader.

中打印数字
        //writer.c

    #include <stdio.h> 
    #include <sys/ipc.h> 
    #include <sys/msg.h> 

    // structure for message queue 
    struct mesg_buffer { 
        int mesg_type; 
        int a[5];

    } message; 

    int main() 
    { 
    message.a [0] = 5;
    message.a [1] = 10;
    message.a [2] = 15;
    message.a [3] = 34;
    message.a [4] = 34;

        key_t key; 
        int msgid; 

        // ftok to generate unique key 
        key = ftok(".", 65); 

        // msgget creates a message queue 
        // and returns identifier 
        msgid = msgget(key, 0666 | IPC_CREAT); 
        message.mesg_type = 1; 

 // msgsnd to send message 
    for(int i=0;i<5;i++)
    msgsnd(msgid, (int *) &message.a[i], sizeof(message.a[i]), 0);



        // display the message 
    for(int i=0;i<5;i++)
        printf("Data send is : %d \n", message.a[i]); 

        return 0; 
    } 

reader.c

 // C Program for Message Queue (Reader Process) 
#include <stdio.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 

// structure for message queue 
struct mesg_buffer { 
    int mesg_type; 
    int a[5];
} message; 

int main() 
{ 
    key_t key; 
    int msgid; 

    // ftok to generate unique key 
    key = ftok(".", 65); 

    // msgget creates a message queue 
    // and returns identifier 
    msgid = msgget(key, 0666 | IPC_CREAT); 

    // msgrcv to receive message
    for(int i=0; i<5; i++)
   msgrcv(msgid, &message, sizeof(message.a[i]), 1, 0); 

    for(int i=0; i<5; i++)
    printf("Data Received is : %d \n",  
                    message.a[i]); 

    // to destroy the message queue 
    msgctl(msgid, IPC_RMID, NULL); 

    return 0; 
} 

我 运行 首先 writer.c 这就是我的输出:

Data send is : 5

Data send is : 10

Data send is : 15

Data send is :34

Data send is : 34

但是当我 运行 reader.c 时,程序卡住了,没有任何反应。有什么关于如何传递数组的建议吗?

编辑: 似乎只传递 msgsnd 和 msgrcv 中的消息解决了问题。

for(int i=0;i<5;i++)
    msgsnd(msgid, &message, sizeof(message), 0); 

您的代码调用了未定义的行为。

既然你想逐个整数地发送,你应该使用sizeof(message.a[i]),一个元素的大小,而不是sizeof(message.a),它是整个数组的大小[=13] =].

msgsnd(msgid, (int *) &message.a[i], sizeof(message.a), 0);
                                            ^^^^^^^^^

简而言之,这意味着您在数组后面传递了一些垃圾。

编辑:阅读 man msgsnd 有点接近之后,看起来类型应该是发送的每条消息的第一个字段,但您传递的每个字段每个 msgsnd 调用的结构都是单独的,因此不会包含该类型。如果你想发送单个单词,你要么需要一次发送整个结构,要么有一些中间结构类型。

这里可能还有其他一些问题。 reader 似乎根本没有收到任何消息。我将从检查与队列 opening/sending/receiving 相关的所有系统调用的 return 值开始,并在出现意外结果时调用 perror()。

第三,正如前面的评论所提到的,对 msgsnd 的调用可能不会正确通过,因为您确实需要 sizeof(message.a[i])。这绝对是一个问题,但它不应该阻止发送第一条消息

第四(这个应该不会导致当前的问题),一旦您接收到 reader,它将在每次调用 msgrcv 时覆盖 message.a 的内容。您需要找到一种方法来保存接收到的数据,然后再将其读入消息。

man msgsnd

The msgp argument is a pointer to caller-defined structure of the following general form:

struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};

所以

msgsnd(msgid, (int *) &message.a[i], sizeof(message.a[i]), 0);

是错误的,您必须为每个想要的值提供完整的消息,所以发送