0

我的任务是将一些使用 System V 队列的 C/C++ 代码从 HP-UX 移植到 Red Hat Linux (SVr4)。

大多数电话都翻译得很好,但我在一个特定问题上遇到了困难,因为它与在给定队列中发现等待的读者和作者有关。

在 HP 上,可以使用msgctl(IPC_STAT)获取有关给定队列的详细信息的 msqid_ds 结构。

这个结构的细节中有一个 short value msqid_ds.msg_perm.mode,它使用低 9 位来指定 user/group/others 的 r/w 权限。

但是,在 HP 上,高 7 位存储其他状态信息,其中包括以下两个标志的标志:

#define MSG_QWAIT       00001   /* a writer is waiting on qp->msg_cbytes */
#define MSG_FWAIT       00002   /* a writer is waiting on msgfp */

这允许人们进行测试,例如,(msqid.msg_perm.mode & (MSG_RWAIT | MSG_WWAIT))查看队列中是否有读取器或写入器阻塞。

当我移植到 Linux 时,很明显这种能力是不一样的。这些标志的定义是不存在的,msqid_ds.msg_perm.mode并且显然不存在较高位信息的值。

但肯定存在维护这些队列的读取器和写入器的内核操作。我希望可以调用一些操作来发现这些信息。

4

1 回答 1

0

据我所知,Linux 没有面向用户的工具来获取您所需要的信息。POSIX 也没有定义任何这样的工具(甚至没有为POSIX消息队列定义)。当然,内核必须维护消息队列状态是对的,但我没有看到可以从用户空间查询该信息的现有机制。除非您喜欢为内核编写驱动程序,否则我认为您的移植需要进行比您希望的更深层次的更改。

但从长远来看,这不一定是坏事。调整您的代码,使其仅依赖于标准设施,而不是供应商扩展,可以预期使其更健壮、更易于维护和更便携。根据遗留代码试图做什么,您甚至可能最终在受影响的区域获得一个更好的设计。

例如,考虑程序为什么需要相关信息,以及它将如何处理这些信息。我只看到一个很好的理由:测试是由进程/线程执行的,作为压力释放机制的一部分,如果队列被太多/太大的消息阻塞,一些消息将被丢弃。我考虑的所有其他原因要么是考虑不周,要么是通过使用非阻塞发送和/或接收来更好地​​服务。如果您的程序的原因属于后者,那么它有更好的方法来完成它想要做的事情。

即使目的是上述压力释放,请注意,您获得的有关消息队列瞬态状态的任何信息都可能在程序得到它之前就已经过时了。在您的程序对收集到的信息采取行动之前,所有被阻止的发件人可能已成功进行,并且新的邮件发送尝试可能已被阻止。这也许是一个可以理解的约束,但它应该为您的减压策略提供参考。在这种情况下,您至少有以下选择:

  • 与其尝试确定是否有任何发件人被阻止,不如确定队列是否达到其容量。您可以从标准中确定struct msqid_ds当前和最大排队消息数。您还可以确定队列可以容纳的最大字节数,尽管没有标准方法来确定当前排队的字节数。(但是,如果您仍然迷恋供应商扩展,则有一种特定于 Linux 的方式。)

  • 通过尝试向其发送消息(使用非阻塞发送)来检查队列是否被阻塞。成功后,立即再次删除该消息。您可以使用消息类型将这些消息与应用程序的其他消息区分开来。在其他接收者的一些合作下,您可以使用消息类型来确保没有其他接收者收到这些探测消息。

于 2016-10-03T15:20:26.403 回答