C IPC - 无法从队列接收消息

C IPC - cannot receive message from queue

我用 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);
}

而这个程序returns预期输出:

Starting... ID of the created queue: 327680 Message queue id: 327680 Received: Hello Stop.

这是怎么回事?怎么了?如何调试?

还有一个问题是创建结构变量的最佳方法是什么 - 指针还是非指针(顺便说一下,结构的非指针变量的名称是什么?)?

Message msg;Message* msg = malloc(sizeof(Message));

您没有初始化消息的 type 字段。 msgsnd 要求类型字段具有正整数值。

您应该更改代码,以便它检查每个具有 return 值的函数的 return 值。我通过将 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 的 return 值。

对于像这样的小结构,没有必要malloc除非你需要结构在创建它的函数退出后继续存在。如果函数只是要使用消息结构并丢弃它,请在本地声明它。如果函数要 return 一个消息结构给它的调用者,用 malloc 和 return 指针分配它。 (然后调用者负责稍后通过将其指针传递给 free 来释放它。)