msgxrcv 子例程

用途

接收扩展消息。

标准 C 库 (libc.a)

语法

#include <sys/msg.h>

int msgxrcv (MessageQueueID, MessagePointer, MessageSize, MessageType, MessageFlag) int MessageQueueID, MessageFlag; size_t MessageSize; struct msgxbuf * MessagePointer; long MessageType;

描述

msgxrcv子程序从MessageQueueID参数指定的队列中读取消息,并将其存储到MessagePointer参数指向的扩展消息接收缓冲区中。 当前进程必须具有读许可权才能执行此操作。 msgxbuf 结构在 sys/msg.h 文件中定义。

注: 在 64 位应用程序调用 32 位内核接口时,如果传递了无效指针,那么例程可以执行 coredump 而不是返回 Efault。

以下限制适用于消息队列:

  • 最大消息大小为 4 兆字节。
  • 每个队列的最大消息数为 8192。
  • 最大消息队列标识数为 131072。
  • 队列中的最大字节数为 4 兆字节。
注: 对于 64 位进程, mtype 字段的长度为 64 位。 但是,为了与 32 位进程兼容, mtype 字段必须是符号扩展为 64 位的 32 位符号值。 最重要的 32 位未放在消息队列上。 对于 64 位进程, mtype 字段再次被符号扩展为 64 位。

参数

描述
MessageQueueID 指定消息队列标识。
MessagePointer 指定指向存储消息的扩展消息接收缓冲区的指针。
MessageSize 指定mtext以字节计的字段。 如果接收消息大于 MessageSize 参数并且 MSG_NOERROR 值为 true ,那么该消息将截断为 MessageSize 参数指定的大小。 消息的截断部分将丢失,并且不会向调用进程提供截断指示。 如果消息的长度超过 MessageSize 参数指定的字节数,并且未设置 MSG_NOERROR 值,那么 msgxrcv 子例程将失败并将 errno 全局变量设置为 E2BIG 错误代码。
MessageType 指定请求的消息类型,如下所示:
  • 如果 MessageType 参数等于 0 ,那么将接收到队列上的第一条消息。
  • 如果 MessageType 参数大于 0 ,那么将收到 MessageType 参数指定的类型的第一条消息。
  • 如果 MessageType 参数小于 0 ,那么将接收到小于或等于 MessageType 参数的绝对值的最低类型的第一条消息。
MessageFlag 指定值 0 或通过逻辑 OR 运算以下一个或多个值来构造的值:
MSG_NOERROR
如果消息长度超过 MessageSize 参数指定的字节数,那么截断该消息。
IPC_NOWAIT
指定在队列中未包含所需类型的消息时要执行的操作:
  • 如果设置了IPC_NOWAIT值,调用进程将返回-1,并将errno全局变量设置为ENOMSG错误代码。
  • 如果未设置 IPC_NOWAIT 值,那么调用进程将暂挂执行,直到发生下列其中一个情况为止:
    • 将所需类型的消息放置在队列上。
    • 从系统中删除MessageQueueID参数指定的消息队列标识符。 当出现这种情况时,全局变量 errno将被设置为EIDRM错误代码,并返回-1值。
    • 调用进程接收要捕获的信号。 在这种情况下,将不接收消息,并且将以 sigaction 子例程中规定的方式恢复调用进程。

返回值

成功完成后, msgxrcv 子例程返回一个值,该值等于实际存储到mtext字段,并对与MessageQueueID参数关联的数据结构执行以下操作:

  • msg_qnum字段由 1 递减。
  • msg_lrpid字段设置为等于调用进程的进程标识。
  • msg_rtime字段设置为等于当前时间。

如果msgxrcv子程序不成功,则返回值为-1,并设置errno全局变量来指示错误。

错误代码

如果满足下列任何条件,那么 msgxrcv 子例程将失败:

描述
EINVAL MessageQueueID参数不是有效的消息队列标识符。
EACCES 拒绝调用进程对指定操作的许可权。
EINVAL MessageSize 参数小于 0。
E2BIG mtext字段大于 MessageSize 参数,并且未设置 MSG_NOERROR 值。
ENOMSG 队列不包含所需类型的消息,并且设置了 IPC_NOWAIT 值。
Efault MessagePointer 参数指向进程地址空间外部。
EINTR msgxrcv 子例程被信号中断。
EIDRM 从系统中删除MessageQueueID参数指定的消息队列标识符。