是否有一种方法可以发送EOF到读取消息队列的进程



我有一个进程通过具有msgsnd的消息队列发送数据。另一个进程使用msgrcv从队列中读取数据。读取进程需要等待,直到它有了所有的消息后才能继续。我怎样才能知道所有的消息都已发送?

我一直在这样做的方式是在发送者发送了所有的消息之后,它然后检查队列中while循环中的消息数量。当没有更多消息时,它关闭队列。

告诉读取进程继续做其他事情。但这似乎不太可靠。很多时候,发送进程会陷入检查队列状态的无限循环中。

是否有一种方法可以让我只发送EOF消息并让阅读过程监视它?然后我可以发送EOF并让发送进程退出。

通常情况下,接收方会注意到发送方已经完成发送,因为它会尝试接收下一条消息,而receive调用表明没有任何东西可以接收。通过文件描述符(管道,套接字)进行通信,关闭是您"发送EOF"的方式,read调用返回0字节。对于消息队列,这有点不同,因为它们是基于消息而不是流,并且通常有多个发送者。

可以用IPC_RMID命令调用msgctl。这将导致对msgrcv(或msgsnd)的任何等待或后续调用返回-EIDRM(在某些BSD系统上为-EINVAL)。这种方法的问题是队列中可能存在等待消息,而接收方尚未读取这些消息,因此我们将丢失这些消息。

相反,当发送方没有其他事情可做时,让它向队列发送一条消息,说"我完成了"。在接收者中,当您收到此消息时,删除队列。当您在一个进程的线程之间使用队列时,这种方法非常有效。如果存在多个进程,则发送方可能在没有发送终止消息的情况下死亡。

如何处理多进程情况将取决于你的应用程序的结构,特别是当发送者死亡时,读取进程想要做什么。检测这种情况的一种方法是在发送方和接收方之间设置一个管道。在接收器上设置一个线程监听该管道;如果它检测到文件的结尾,它可以

    设置一个与调用msgrcv的线程共享的变量;
  1. 查看队列(msgctlIPC_STAT);
  2. 如果队列为空(msg_qnum == 0),将其删除。

最新更新