Perl: msgsnd函数的参数

3
我是一名维护现有代码的人员。
我看到了这个片段:
msgsnd( $mQueue, pack("l! a*", length($msg), $msg), 0) 
                                   || ... error handling ...

我想了解将pack()调用作为msgsnd的第二个参数的含义。
我在msgsend文档中找到了以下内容:
调用System V IPC函数msgsnd将消息MSG发送到消息队列ID。MSG必须以本机长整型消息类型开头,后跟实际消息的长度,最后是消息本身。这种打包可以使用pack("l! a*", $type, $message)来实现。如果成功,则返回true;如果出错,则返回false。另请参见perlipc中的SysV IPC和IPC :: SysV和IPC :: Msg的文档。
这将第二个参数传递给pack作为$type,但没有解释$type是什么。我正在尝试理解的代码传递了消息长度。
发生了什么?据我所知,现有代码可靠地工作。

2
参见:http://ods.com.ua/win/eng/program/Perl5Unleashed/ch13.phtml。从该示例(链接中的清单13.2)来看,文档是正确的,而您的代码示例是不正确的。 - Håkon Hægland
1
你在文档中发现了一个错误。"紧随其后的是实际消息的长度" 是无意义的,应该删除。另一方面,你的代码也没有太多意义,因为它将长度作为消息类型传递。 - melpomene
2
顺便提一下,这是Perl中的msgsnd代码。它显示消息大小会自动从您传递的字符串计算出来。 - melpomene
是的,我非常确定我在一个充满错误代码和可疑文档的迷宫中。$type参数应该取哪些值? - djna
1
为此,您应该参考man 2 msgsnd,正如Leonard的回答所说:“*mtype字段必须具有严格的正整数值。接收进程可以使用此值进行消息选择(请参阅下面的msgrcv()描述)*”。系统本身并不关心;这只对接收者有意义。 - melpomene
3个回答

2
msgsnd的手册页中提到:“mtext字段是一个数组(或其他结构),其大小由msgsz指定,这是一个非负整数值。允许长度为零的消息(即没有mtext字段)。mtype字段必须具有严格的正整数值。接收进程可以使用该值进行消息选择(请参见下面的msgrcv()描述)。”因此,在sndmsg本身中未使用类型,并且类型字段中显示的长度可能会或可能不会在接收端使用。

2

这个应用程序决定使用类型字段来存储消息的长度。

(这相当奇怪,因为消息的大小已经对读者可用。)


当接收方从系统请求消息时,他们可以将请求限制为特定的消息类型。

  • 如果msgtyp为0,则读取队列中的第一条消息。

  • 如果msgtyp大于0,则读取类型为msgtyp的队列中的第一条消息,除非在msgflg中指定了MSG_EXCEPT,在这种情况下,将读取不等于msgtyp的类型的队列中的第一条消息。

  • 如果msgtyp小于0,则读取类型小于或等于msgtyp的绝对值的最低类型的队列中的第一条消息。

如果接收方将msgtyp指定为0,则发送方提供的消息类型不被系统使用,因此可以用于携带其他信息。


@djna,如果它回答了你的问题,请在旁边打勾 :) - ikegami

0

它创建了消息的二进制表示:len msg。通过以下方式进行检查:

perl -e '$a= "abcde"; print(pack("l! a*", length($a), $a))' | od -c

给出:

 0000000 005  \0  \0  \0  \0  \0  \0  \0   a   b   c   d   e

0000015


谢谢,那很清楚了,除了似乎与文档不一致。为什么文档会说“pack(”l!a *“,$type,$message)”?我看到的是$ msg而不是$type的长度。 - djna
请查看 pack 的文档,它会澄清一些事情。pack 的使用方式取决于您的应用程序。请参阅此文档:https://perldoc.perl.org/perlpacktut.html,其中包含许多示例。 - hootnot
谢谢,我所引用的Perl文档与您提到的教程中的示例之间似乎存在明显的不一致性。 - djna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接