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 指定,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) 没有内在限制。参见
广告
|