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

时间:2018-01-06 22:58:59

标签: c linux pointers ipc

我在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));

1 个答案:

答案 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来释放它。)