在我的程序中,当进程从消息队列接收到消息“ON”时,我尝试分叉一个进程。在引入分叉之前,消息可以正常工作:
while (1)
{
receive_message(msg_queue_id, data, sizeof(data), getpid());
if (strcmp(data, "ON") == 0)
{
puts("Received");
}
}
但是,添加分叉后,程序表现出不一致的行为。最初的 10 个进程似乎受到了影响,值得注意的是,fork 并不总是失败;有成功的例子。
while (1)
{
receive_message(msg_queue_id, data, sizeof(data), getpid());
if (strcmp(data, "ON") == 0)
{
pid = fork();
CATCH_ERROR;
if (pid == 0)
{
puts("Received");
}
}
}
fork失败时遇到的错误信息如下:
[错误] src/proc.c 行:32 PID = 22755 错误 42(没有所需类型的消息)
我很难理解为什么间歇性地分叉进程会导致消息队列出现问题。任何有关潜在原因以及如何解决这些问题的见解或建议将不胜感激。
我的期望是分叉进程不会干扰消息队列操作,但间歇性的“没有所需类型的消息”错误表明情况并非如此。我正在寻找潜在原因或替代方法来解决此问题。
void receive_message(int msg_id, void *msg_ptr, size_t msg_size, int msg_type)
{
struct msqid_ds buf;
struct msgbuf message;
message.mtype = msg_type;
if (msgctl(msg_id, IPC_STAT, &buf) == -1)
{
if (errno != ENOMSG)
CATCH_ERROR;
return;
}
if (buf.msg_qnum == 0)
return;
if (msgrcv(msg_id, &message, msg_size, msg_type, IPC_NOWAIT) == -1)
{
if (errno != ENOMSG)
CATCH_ERROR;
return;
}
memcpy(msg_ptr, message.mtext, msg_size);
}
假设一个进程从消息队列中读取“ON”。它写入“已接收”,然后尝试读取另一条消息。
msgrcv
返回-1并将errno
设置为ENOMSG,因此receive_message
返回时不会向msg_ptr
写入任何数据,并且data
仍然包含上次读取的“ON”。 strcmp
再次返回 0,fork
被调用,父级和子级立即调用 CATCH_ERROR
宏,该宏(大概)根据当前 errno
中的内容写入错误消息。如果 strcmp
和 fork
都没有修改 errno
,那么该值仍然是 ENOMSG
,并且您会看到令人讨厌的错误消息。