msgop() - Unix, Linux系统调用
Tutorials Point


  Unix入门
  Unix Shell编程
  高级Unix
  Unix有用参考
  Unix有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论区     关于TP  

msgop() - Unix, Linux系统调用


previous next AddThis Social Bookmark Button

广告

名称

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 标志的设置如何,msgsndmsgrcv 永远不会在被信号处理程序中断后自动重启。)

成功完成时,消息队列数据结构将更新如下:

标签描述
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) 没有固有的限制。

参见



previous next Printer Friendly

广告


  

广告



广告