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) 来实现。成功返回真,错误返回假。另请参阅 perlipc 中的 SysV IPC 以及 IPC::SysV 和 IPC::Msg 的文档。

这给出了要打包为 $type 的第二个参数,但没有解释 $type 是什么。我试图理解的代码改为传递消息长度。

这是怎么回事?据我所知,现有代码运行可靠。

4

3 回答 3

2

msgsnd的手册页说“mtext 字段是一个数组(或其他结构),其大小由 msgsz 指定,一个非负整数值。允许长度为零的消息(即,没有 mtext 字段)。mtype 字段必须具有严格的正整数值。这个值可以被接收进程用于消息选择(见下面 msgrcv() 的描述)。

因此 sndmsg 本身不使用类型,并且出现在类型字段中的长度可能会或可能不会在接收端使用。

于 2018-07-08T11:07:14.010 回答
2

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

(这很奇怪,因为消息的大小已经可供读者使用。)


当接收者向系统请求消息时,他们可能会将请求限制为特定的消息类型。

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

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

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

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

于 2018-07-08T11:24:11.653 回答
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

于 2018-07-08T11:05:03.297 回答