msgop() - Unix, Linux系统调用
广告
名称msgop - 消息操作概要
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
|
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); 描述msgsnd() 和 msgrcv() 系统调用分别用于向消息队列发送消息和从消息队列接收消息。调用进程必须对消息队列具有写权限才能发送消息,并具有读权限才能接收消息。msgp 参数是指向调用者定义的结构体的指针,其一般形式如下:
struct msgbuf {
long mtype; /* 消息类型,必须 > 0 */
char mtext[1]; /* 消息数据 */
}; mtext 字段是一个数组(或其他结构体),其大小由非负整数值 msgsz 指定。允许长度为零的消息(即没有 mtext 字段)。mtype 字段必须具有严格的正整数值。接收进程可以使用此值进行消息选择(参见下面 msgrcv() 的描述)。 msgsnd() 系统调用将 msgp 指向的消息的副本附加到其标识符由 msqid 指定的消息队列中。 如果队列中有足够的可用空间,msgsnd() 会立即成功。(队列容量由消息队列关联数据结构中的 msg_bytes 字段定义。在队列创建期间,此字段初始化为 MSGMNB 字节,但可以使用 msgctl() 修改此限制。)如果队列中没有足够的可用空间,则 msgsnd() 的默认行为是阻塞,直到有可用空间为止。如果在 msgflg 中指定了 IPC_NOWAIT,则调用将改为失败,并返回错误 EAGAIN。 如果队列被删除(在这种情况下,系统调用失败,errno 设置为 EIDRM),或者捕获到信号(在这种情况下,系统调用失败,errno 设置为 EINTR),则被阻塞的 msgsnd() 调用也可能失败。(无论在建立信号处理程序时 SA_RESTART 标志的设置如何,msgsnd 和 msgrcv 永远不会在被信号处理程序中断后自动重启。) 成功完成时,消息队列数据结构将更新如下:
标签 | 描述 |
|
msg_lspid 设置为调用进程的进程 ID。 |
|
msg_qnum 增加 1。 |
|
msg_stime 设置为当前时间。 |
系统调用 msgrcv() 从 msqid 指定的队列中删除一条消息,并将其放入 msgp 指向的缓冲区中。 |
参数 msgsz 指定 msgp 参数指向的结构体的 mtext 成员的最大大小(以字节为单位)。如果消息文本的长度大于 msgsz,则行为取决于 msgflg 中是否指定了 MSG_NOERROR。如果指定了 MSG_NOERROR,则消息文本将被截断(并且截断的部分将丢失);如果没有指定 MSG_NOERROR,则消息不会从队列中删除,系统调用失败并返回 -1,errno 设置为 E2BIG。 |
参数 msgtyp 指定请求的消息类型,如下所示: |
| 如果 msgtyp 为 0,则读取队列中的第一条消息。 |
| 如果 msgtyp 大于 0,则读取队列中类型为 msgtyp 的第一条消息,除非在 msgflg 中指定了 MSG_EXCEPT,在这种情况下,将读取队列中类型不等于 msgtyp 的第一条消息。 |
| 如果 msgtyp 小于 0,则读取队列中类型小于或等于 msgtyp 的绝对值的最低类型的第一条消息。 |
msgflg 参数是一个位掩码,通过将以下一个或多个标志进行按位或运算来构造: |
IPC_NOWAIT | | 如果队列中没有请求类型的消息,则立即返回。系统调用失败,errno 设置为 ENOMSG。 |
MSG_EXCEPT | | 与 msgtyp 大于 0 一起使用,以读取队列中消息类型与 msgtyp 不同的第一条消息。 |
MSG_NOERROR | | 如果消息文本长度超过 msgsz 字节,则截断消息文本。 |
如果找不到请求类型的消息并且在 msgflg 中未指定 IPC_NOWAIT,则调用进程将被阻塞,直到发生以下情况之一: |
| 将请求类型的消息放入队列中。 |
| 消息队列从系统中删除。在这种情况下,系统调用失败,errno 设置为 EIDRM。 |
| 调用进程捕获到信号。在这种情况下,系统调用失败,errno 设置为 EINTR。 |
成功完成时,消息队列数据结构将更新如下: |
|
msg_lrpid 设置为调用进程的进程 ID。 |
|
msg_qnum 减少 1。 |
|
msg_rtime 设置为当前时间。 |
返回值如果失败,两个函数都返回 -1,errno 指示错误,否则 msgsnd() 返回 0,msgrcv() 返回实际复制到 mtext 数组中的字节数。错误当 msgsnd() 失败时,errno 将设置为以下值之一:
标签 | 描述 |
EACCES | 调用进程对消息队列没有写权限,并且没有 CAP_IPC_OWNER 能力。 |
EAGAIN | 由于队列的 msg_qbytes 限制,无法发送消息,并且在 msgflg 中指定了 IPC_NOWAIT。 |
EFAULT | msgp 指向的地址不可访问。 |
EIDRM | 消息队列已被删除。 |
EINTR | 在消息队列已满的条件下休眠,进程捕获到信号。 |
EINVAL | msqid 值无效,或 mtype 值非正,或 msgsz 值无效(小于 0 或大于系统值 MSGMAX)。 |
ENOMEM | 系统没有足够的内存来复制 msgp 指向的消息。 |
当 msgrcv() 失败时,errno 将设置为以下值之一: |
E2BIG | 消息文本长度大于 msgsz,并且在 msgflg 中未指定 MSG_NOERROR。 |
EACCES | 调用进程对消息队列没有读权限,并且没有 CAP_IPC_OWNER 能力。 |
EAGAIN | 队列中没有可用的消息,并且在 msgflg 中指定了 IPC_NOWAIT。 |
EFAULT | msgp 指向的地址不可访问。 |
EIDRM | 在进程休眠以接收消息时,消息队列已被删除。 |
EINTR | 在进程休眠以接收消息时,进程捕获到信号。 |
EINVAL |
msgqid 无效,或 msgsz 小于 0。 |
ENOMSG |
在 msgflg 中指定了 IPC_NOWAIT,并且消息队列中不存在请求类型的消息。 |
符合标准SVr4, POSIX.1-2001。备注msgp 参数在 libc4、libc5、glibc 2.0、glibc 2.1 中声明为 struct msgbuf *。根据 SUSv2 和 SUSv3 的要求,它在 glibc 2.2 及更高版本中声明为 void *。以下消息队列资源限制会影响 msgsnd() 调用:
标签 | 描述 |
MSGMAX | 消息文本的最大大小:8192 字节(在 Linux 上,此限制可以通过 /proc/sys/kernel/msgmax 读取和修改)。 |
MSGMNB | 消息队列的默认最大大小(以字节为单位):16384 字节(在 Linux 上,此限制可以通过 /proc/sys/kernel/msgmnb 读取和修改)。超级用户可以通过 msgctl() 系统调用将消息队列的大小增加到超过 MSGMNB。 |
实现对系统范围内的最大消息头数 (MSGTQL) 和系统范围内的消息池的最大大小 (MSGPOOL) 没有固有的限制。参见
广告
|