我在C中编写了一个使用IPC消息队列的简单程序,但是当我将其作为指针发送时,我无法收到消息。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <error.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <ctype.h>
#include <string.h>
typedef struct Message {
long type;
char content[16];
} Message;
int main(int argc, char* argv[]) {
printf("Starting...\n");
key_t key = 1;
Message* msg = malloc(sizeof(Message));
int msg_id = msgget(key, IPC_CREAT | 0777);
printf("ID of the created queue: %d\n", msg_id);
strcpy(msg->content, "Hello");
msgsnd(msg_id, msg, 16, 0);
free(msg);
if (fork() == 0) {
int msgid = msgget(key, 0);
printf("Message queue id: %d\n", msgid);
Message rcvMsg;
msgrcv(msgid, &rcvMsg, 16, 0, 0);
printf("Received: %s\n", rcvMsg.content);
if (msgctl(msgid, IPC_RMID, 0) != 0) {
perror("Cannot remove queue from system.\n");
exit(1);
}
exit(0);
}
wait(NULL);
printf("Stop.\n");
exit(0);
}
我得到的输出是:
Starting...
ID of the created queue: 327680
Message queue id: 327680
节目正在等待。 但是,当我发送一条消息作为标准变量 - 而不是指向结构的指针时 - 就会传递消息。
工作计划:
int main(int argc, char* argv[]) {
printf("Starting...\n");
key_t key = 1;
Message msg;
int msg_id = msgget(key, IPC_CREAT | 0777);
printf("ID of the created queue: %d\n", msg_id);
strcpy(msg.content, "Hello");
msgsnd(msg_id, &msg, 16, 0);
if (fork() == 0) {
int msgid = msgget(key, 0);
printf("Message queue id: %d\n", msgid);
Message rcvMsg;
msgrcv(msgid, &rcvMsg, 16, 0, 0);
printf("Received: %s\n", rcvMsg.content);
if (msgctl(msgid, IPC_RMID, 0) != 0) {
perror("Cannot remove queue from system.\n");
exit(1);
}
exit(0);
}
wait(NULL);
printf("Stop.\n");
exit(0);
}
此程序返回预期输出:
Starting...
ID of the created queue: 327680
Message queue id: 327680
Received: Hello
Stop.
发生了什么?怎么了?如何调试?
还有一个问题是创建结构变量的最佳方法是什么 - 指针或非指针(顺便说一句。结构的非指针变量的名称是什么?)?
Message msg;
或Message* msg = malloc(sizeof(Message));
答案 0 :(得分:4)
您没有初始化邮件的type
字段。 msgsnd
要求type字段具有正整数值。
您应该更改代码,以便检查具有返回值的每个函数的返回值。我发现此错误的方法是将msgsnd(msg_id, msg, 16, 0);
更改为int result = msgsnd(msg_id, msg, 16, 0);
,然后插入:
if (result == -1)
{
perror("msgsnd");
exit(EXIT_FAILURE);
}
这告诉我msgsnd
有一个无效的论点,所以我查看了它的文档,发现type
必须是正面的。
您还应该检查msgrcv
的返回值。
对于像这样的小结构,除了在创建它的函数退出后需要结构继续存在之外,不需要malloc
。如果函数只是使用消息结构并丢弃它,请在本地声明它。如果函数要将消息结构返回给其调用者,请使用malloc
分配它并返回指针。 (然后调用者负责通过将其指针传递给free
来释放它。)