Linux Posix 消息队列:消息太长

问题描述 投票:0回答:1

我想做的是,当子进程在文件上找到素数时,父进程应该将它们写入另一个文件。子进程将发送素数作为 M 个数字的消息。但是,我无法接收消息,出现

Message too long
错误。

int main() {
    mqd_t mq;
    mq = mq_open(MQ_NAME, O_RDWR | O_CREAT, 0666, NULL);
    if (mq == (mqd_t) - 1) {
        perror("Cannot create msg queue");
        exit(EXIT_FAILURE);
    }

    // Start child processes
    for (int i = 0; i < N; i++) {
        pid_t pid = fork();

        if (pid < 0) {
            perror("Fork failed");
            exit(EXIT_FAILURE);
        } else if (pid == 0) {
            char fileName[26];
            sprintf(fileName, "inter_file_%d.txt", i);
            FILE *file = fopen(fileName, "r");
            if (file == NULL) {
                perror("Intermediate file open failed on child process");
                exit(EXIT_FAILURE);
            }

            int64_t number;
            int64_t message[M];

            int curr_msg_size = 0;
            while (fscanf(file, "%" PRId64, &number) == 1) {
                if (isPrime(number)) {
                    message[curr_msg_size] = number;

                    if (curr_msg_size == (M - 1)) { // Message if fulled
                        int res = mq_send(mq, (const char *) message, (curr_msg_size + 1) * sizeof(int64_t), 0);

                        if (res == -1) {
                            perror("mq_send failed on full message");
                            exit(EXIT_FAILURE);
                        }
                        curr_msg_size = 0;
                    }
                    curr_msg_size += 1;
                }
            }

            if (curr_msg_size > 0) {
                int res = mq_send(mq, (const char *) message, curr_msg_size * sizeof(int64_t), 0);

                if (res == -1) {
                    perror("mq_send failed on partial message");
                    exit(EXIT_FAILURE);
                }
            }

            fclose(file);
            remove(fileName); // Remove the intermediate file
            exit(EXIT_SUCCESS); // Child process terminates
        }
    }

    // Wait for all child processes to terminate
    for (int i = 0; i < N; i++) {
        int status;
        wait(&status);
    }

    // Open the output file
    FILE *output_file = fopen(output_file_name, "w");
    if (output_file == NULL) {
        perror("Output file open failed on parent process");
        exit(EXIT_FAILURE);
    }

    // Read from the message queue and write to the output file
    int64_t message[M];
    while (mq_receive(mq, (char *) message, M * sizeof(int64_t), NULL) != -1) {
        for (int i = 0; i < M; i++) {
            if (message[i] != 0) {
                fprintf(output_file, "%" PRId64 "\n", message[i]);
            }
        }
    }

    // Close the output file
    if (fclose(output_file) != 0) {
        perror("Output file close failed on parent process");
        exit(EXIT_FAILURE);
    }

    // Close and unlink the message queue
    mq_close(mq);
    mq_unlink(MQ_NAME);

    return 0;
}

我想我使用 mq_receive 方法是错误的,我希望有人能看到我的错误并告诉我。

c linux posix message-queue
1个回答
0
投票

如果

mq_send函数
将返回
EMSGSIZE

错误

msg_len
大于 比消息队列的
mq_msgsize
属性

如果

mq_receive函数
将返回
EMSGSIZE

错误

msg_len
比消息队列的 mq_msgsize 属性

[在引号中强调我的]

mq_msgsize
属性通过
mq_open
函数
设置,根据消息队列概述手册页默认为
8192
字节。

由于您没有设置该属性,因此它将是默认值。所以当你发送时,你必须保持消息小于

8192
字节。并且当你接收时,你需要有至少
8192
字节的缓冲区。

由于您没有向我们提供最小的可重现示例,我们不知道

M
是什么,或者尝试发送或接收多少字节。


今天的课程:务必阅读相关手册页。

© www.soinside.com 2019 - 2024. All rights reserved.