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 的内容。您需要找到一种方法来保存接收到的数据,然后再将其读入消息。
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);
是错误的,您必须为每个想要的值提供完整的消息,所以发送
我有 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 的内容。您需要找到一种方法来保存接收到的数据,然后再将其读入消息。
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);
是错误的,您必须为每个想要的值提供完整的消息,所以发送