我想做的是,当子进程在文件上找到素数时,父进程应该将它们写入另一个文件。子进程将发送素数作为 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 方法是错误的,我希望有人能看到我的错误并告诉我。
,
mq_send
函数将返回
EMSGSIZE
错误
大于 比消息队列的msg_len
属性mq_msgsize
,
mq_receive
函数将返回
EMSGSIZE
错误
比消息队列的msg_len
mq_msgsize
属性少
[在引号中强调我的]
mq_msgsize
属性通过mq_open
函数设置,根据消息队列概述手册页默认为8192
字节。
由于您没有设置该属性,因此它将是默认值。所以当你发送时,你必须保持消息小于
8192
字节。并且当你接收时,你需要有至少8192
字节的缓冲区。
由于您没有向我们提供最小的可重现示例,我们不知道
M
是什么,或者尝试发送或接收多少字节。
今天的课程:务必阅读相关手册页。