C IPC - 无法从队列接收消息
Posted
技术标签:
【中文标题】C IPC - 无法从队列接收消息【英文标题】:C IPC - cannot receive message from queue 【发布时间】:2018-01-06 22:58:58 【问题描述】:我用 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));
【问题讨论】:
"结构的非指针变量的名称是什么" --> "结构". “什么是创建结构变量的最佳方式 - 指针或非指针”应该是“什么是创建数据的最佳方式,作为 结构 或 指向结构的指针?”。 编译所有警告和调试信息:gcc -Wall -Wextra -g
。改进代码以获得没有警告。仔细阅读每个系统调用(参见intro(2))和标准函数(例如malloc(3)..)的文档。阅读ALP。 使用gdb
debugger 或者valgrind
【参考方案1】:
您没有初始化消息的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
来释放它。)
【讨论】:
需要添加msg->type = 1;在msgsnd之前以上是关于C IPC - 无法从队列接收消息的主要内容,如果未能解决你的问题,请参考以下文章