处理mq_unlink之后的mq_open失败

我正在使用Posix消息队列进行通信,在Suse Linux上编写客户机/服务器进程,类似于“ 如何在基于Linux的系统上的ac程序中使用mqueue? ”中的接受答案。 当服务器死亡,它做一个mq_closemq_unlink 。 但是,客户端没有得到这个通知,所以即使队列已经被解除链接 ,在客户端的mq_send的调用也将继续工作。

问题是,当服务器重新启动时,它会尝试使用O_CREAT创build一个mq_open的队列,但由于客户端仍然有一个打开的fd,所以会失败。 所以,即使/ dev / mqueue中的文件名不存在,服务器也不能创build一个,直到客户端退出并closures其文件描述符。 我只是想确定我正确地理解了这一点:如果我想让服务器closures,取消链接,然后重新打开mqueue(例如:具有不同的属性),是否肯定需要客户端退出或closures它的fd? 这与使用普通文件的方式有很大不同:我可以删除另一个进程正在使用的文件,文件系统可能会将其重命名为“.nfsXXX”,他们可以继续使用它,但是我可以创build一个新文件立即使用该名称的文件。

我第一次尝试解决这个问题只是为了不退出服务器退出时的mqueue – 如果我想允许服务器重新启动,而客户端不需要重新启动,那么我想我不应该取消链接队列(因为服务器知道客户端可能仍在使用mqueue,不应该取消链接)。

我最想要发生的事情是新的mq_open在服务器上成功,而下一个mq_send在客户端失败。 有一个简单的方法来模拟这个? 发生在我身上的方式是:

  • 在每个mq_sendyuck !)之前对“/ dev / mqueue / queueName”做一个fstat(或者其他),如果这个名字不存在(当服务器试图在一个循环中重新创build它),closuresfd,如果客户端当前被阻塞在mq_send上因为队列已满而无法正常工作。
  • 在客户端有一个单独的套接字,当服务器希望客户端closures它们的mqueue(可能是客户端中的一个单独的线程来监视该套接字)时,服务器会向其发送消息。
  • 让服务器杀死客户端。

Solutions Collecting From Web of "处理mq_unlink之后的mq_open失败"