英文:
C library message queue didn't read all messages
问题
我运行这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
// 为消息定义一个结构体
struct message {
long msg_type;
char msg_text[100];
};
int main() {
key_t key;
int msg_id;
struct message msg;
// 为消息队列生成一个键
key = ftok("progfile", 'A');
// 创建消息队列
msg_id = msgget(key, 0666 | IPC_CREAT);
// 准备要发送的消息
struct message messages[3] = {{1, "This is message with priority 1"},
{2, "This is message with priority 2"},
{3, "This is message with priority 3"}};
// 发送消息
for (int i = 0; i < 3; i++) {
msgsnd(msg_id, &messages[i], sizeof(messages[i]), 0);
}
// 接收消息
for (int i = 1; i <= 3; i++) {
memset(&msg, 0, sizeof msg);
if (msgrcv(msg_id, &msg, sizeof(msg), 0, IPC_NOWAIT) != -1) {
printf("Received message: %s\n", msg.msg_text);
} else {
printf("No message in the queue\n");
}
}
// 销毁消息队列
msgctl(msg_id, IPC_RMID, NULL);
return 0;
}
我预期的输出应该是打印出所有三条消息,但实际上只打印出:
Received message: This is message with priority 1
No message in the queue
No message in the queue
而且 msgctl
没有运行,因为当我运行 ipcs
时,即使这段代码已经运行完毕,我仍然可以看到消息队列仍然存在。
根据我的阅读,msgrcv(msg_id, &msg, sizeof(msg), 0, IPC_NOWAIT)
应该读取并删除队列中的第一条可用消息,类型参数设置为 0
。但实际上,它只读取了一条消息,然后无法读取任何消息,这让我感到困惑。我使用 gdb 进行了调试,并发现即使消息队列仍然有消息,msgrcv
也无法检索消息。另一件奇怪的事情是,如果我将此代码拆分为两个文件,并在两个进程中运行发送和接收逻辑,接收进程可以读取所有 3 条消息。我不知道其中的差异是什么。谢谢您的任何帮助!
英文:
I'm running this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
// Define a structure for our messages
struct message {
long msg_type;
char msg_text[100];
};
int main() {
key_t key;
int msg_id;
struct message msg;
// Generate a key for the message queue
key = ftok("progfile", 'A');
// Create the message queue
msg_id = msgget(key, 0666 | IPC_CREAT);
// Prepare messages to send
struct message messages[3] = {{1, "This is message with priority 1"},
{2, "This is message with priority 2"},
{3, "This is message with priority 3"}};
// Send the messages
for (int i = 0; i < 3; i++) {
msgsnd(msg_id, &messages[i], sizeof(messages[i]), 0);
}
// Receive the messages
for (int i = 1; i <= 3; i++) {
memset(&msg, 0, sizeof msg);
if (msgrcv(msg_id, &msg, sizeof(msg), 0, IPC_NOWAIT) != -1) {
printf("Received message: %s\n", msg.msg_text);
} else {
printf("No message in the queue\n");
}
}
// Destroy the message queue
msgctl(msg_id, IPC_RMID, NULL);
return 0;
}
What I expect is it prints out all three messages, but actually it only prints:
Received message: This is a message with priority 1
No message in the queue
No message in the queue
And msgctl
did not run because when I ipcs
, I can still see the message queue alive even after this code finished.
From what I read, msgrcv(msg_id, &msg, sizeof(msg), 0, IPC_NOWAIT)
will read and remove the 1st message available, with the type arg set to 0
. But actually, it reads only 1 message and then it cannot read any message, which confused me. I debugged using gdb, and found that even when the message queue still has messages, msgrcv
won't retrieve the message. The other strange thing is, if I split this code into two files and run the send and read logic in two processes, the read process can read all 3 messages. I don't know what is the difference here. Thank you for any help!
答案1
得分: 2
错误出在msgsnd
和msgrcv
,它们应该是
msgsnd(msg_id, &messages[i], sizeof(messages[i].msg_text), 0);
和
if (msgrcv(msg_id, &msg, sizeof(msg.msg_text), 0, IPC_NOWAIT) != -1)
第三个参数msgsz
应该只包含消息的msg_text
的大小。
英文:
The error is in msgsnd
and msgrcv
, they should be
msgsnd(msg_id, &messages[i], sizeof(messages[i].msg_text), 0);
and
if (msgrcv(msg_id, &msg, sizeof(msg.msg_text), 0, IPC_NOWAIT) != -1)
The 3rd arg msgsz
should only contain the size of the msg_text
of the message.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论