我有writer.c和reader.c,我试图从writer发送数组,然后在阅读器中打印数字。
//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,这是我的输出:
数据发送为:5
数据发送为:10
数据发送为:15
数据发送为:34
数据发送为:34
但是当我运行reader.c时,程序卡住了,什么也没发生。有什么建议如何传递数组吗?
编辑:似乎仅在msgsnd和msgrcv中传递了消息,即可解决问题。
for(int i=0;i<5;i++)
msgsnd(msgid, &message, sizeof(message), 0);
答案 0 :(得分:1)
您的代码调用未定义的行为。
由于要按整数发送整数,因此应使用sizeof(message.a[i])
(即一个元素的大小),而不要使用sizeof(message.a)
(即整个数组a
的大小)
msgsnd(msgid, (int *) &message.a[i], sizeof(message.a), 0);
^^^^^^^^^
简而言之,这意味着您正在数组后面传递一些垃圾。
答案 1 :(得分:1)
编辑:仔细阅读 man msgsnd 后,看起来类型应该是发送的每条消息的第一个字段,但是您要分别将结构的每个字段传递给每个消息msgsnd调用,因此不会包含该类型。您需要一次发送整个结构,或者如果要发送单个单词,则需要某种中间结构类型。
这里也可能有其他一些问题。读者似乎根本没有收到任何消息。我将从检查与队列打开/发送/接收有关的所有系统调用的返回值开始,并在出现意外结果的情况下调用perror()。
第三点,如前一条评论所述,由于您确实想要sizeof(message.a [i]),因此对msgsnd的调用可能无法正确进行。绝对是一个问题,但不应阻止发送第一条消息
第四(这不应该引起当前问题),一旦您的读者收到,它将覆盖每次对msgrcv的调用message.a的内容。您需要先找到一种方法来保存接收到的数据,然后再将其读入消息中。
答案 2 :(得分:1)
msgp参数是指向以下一般形式的调用方定义的结构的指针:
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);
是错误的,您必须为要发送的每个值提供完整的消息