消息队列

2015-05-13 18:05:50   最后更新: 2015-05-13 18:05:50   访问数量:843




此前已经介绍了 XSI PIC 的基本概念和一些用法

XSI IPC 简介

 

这里我们介绍一下 XSI IPC 中的消息队列

消息队列简称队列,其标识符被称为队列 ID(queue ID)

 

消息被添加到队列尾端,包含一个正长整型类型字段,一个非负长度以及实际数据字节

消息队列并不一定要以先进先出次序取消息,也可以按照消息的类型字段取消息

 

struct msqid_ds { struct ipc_perm msg_perm; // ipc 权限结构 msgqnum_t msg_qnum; // 队列中的数据数 msglen_t msg_qbytes; // 队列的最大字节容量 pid_t msg_lspid; // 最近插入队列数据的进程 ID pid_t msg_lrpid; // 最近取出数据的进程 ID time_t msg_stime; // 最近入队时间 time_t msg_rtime; // 最近出队时间 time_t msg_ctime; // 最近更新时间 ... ... }

 

 

该结构描述了队列的当前状态,各系统的具体实现会包含额外的字段

 

函数 msgget 的功能是打开一个现存队列或创建一个新的队列

int msgget(key_t key, int flag);

 

定义于 sys/msg.h 中

调用成功返回消息队列 ID,调用出错返回 -1

 

参数取值

  • 参数 key 的取值

  1. 如果 key 取值为 IPC_PRIVATE,则创建新的 IPC 结构
  2. 如果指定的 key 当前未与任何 IPC 结构结合,并且 flag 中指定了 IPC_CREAT 位,则用该 key 创建新的 IPC 结构
  3. 如果指定的 key 当前未与任何 IPC 结构结合,并且 flag 中未指定 IPC_CREAT 位,则函数返回出错
  4. 如果指定的 key 当前已经与 IPC 结构结合,并且 flag 中未指定 IPC_EXECL 位,则返回对应 IPC 结构,否则返回 EEXIST

 

  • 参数 flag 的取值

实际上,在上述参数 key 的取值的介绍中我们已经介绍了 flag 的取值

参数 flag 的取值
取值意义
IPC_CREATkey 不存在则创建
IPC_EXECL通常与 IPC_CREAT 一起使用,强制要求 key 不存在

 

msgctl 函数可以执行多种操作,与 ioctl、semctl、shmctl 非常类似,都被称为“垃圾桶函数”

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

 

定义于 sys/msg.h 中

调用成功返回 0,否则返回 -1

 

cmd 参数说明

cmd 参数说明
取值意义
IPC_STAT取出该队列描述结构,并存放在 buf 指向的结构中
IPC_SET按 buf 指向的结构中的值,设置队列描述结构中的 msg_perm.uid、msg_perm.gid、msg_perm.mode 和 msg_qbytes,但是要求执行该函数进程的有效用户 ID 必须等于 msg_perm.cuid 或 msg_perm.uid,或该进程的有效用户是超级用户,并且只有超级用户才能增加 msg_qbytes 的值
IPC_RMID从系统中删除该消息队列及队列中的所有数据,该操作会立即生效,取数据的进程接下来会立即返回 EIDRM,与 IPC_SET 一样,该操作要求执行该函数进程的有效用户 ID 必须等于 msg_perm.cuid 或 msg_perm.uid,活该进程的有效用户是超级用户

 

int msgsend(int msqid, const void *ptr, size_t nbytes, int flag);

 

定义于 sys/msg.h 中

调用成功返回 0,否则返回 -1

 

ptr 参数说明

参数 ptr 指向需要加入的消息

正如前面介绍的,每条消息都包含正整型的消息类型,其后紧跟消息数据(除非 nbytes 参数为 0 则没有数据)

例如,要发送最长消息为 512 字节,则可以定义下面的结构体,使用 ptr 指向他

struct mymsg { long mtype; // 实际的消息类型 char mytext[512]; // 消息的实际数据 }

 

 

flag 参数说明

如果 flag 取值为 IPC_NOWAIT,则当消息队列已满时,直接返回 EAGAIN,若未指定 IPC_NOWAIT 则进程阻塞直到队列可写(如果在等待过程中队列被删除,则返回 EINTR)

 

ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);

 

定义于 sys/msg.h 中

调用成功返回消息的数据部分长度,否则返回 -1

 

参数说明

  • ptr

返回的消息存储在 ptr 指向的缓冲区中,缓冲区开始部分的长整型标识实际数据的大小

 

  • type
msgrcv 函数的 type 参数取值
取值意义
type == 0返回队列中的第一个消息(先进先出)
type > 0返回队列中消息类型为 type 的消息
type < 0返回队列中消息类型值不大于 type 绝对值的消息中类型值最小的一个消息

 

队列中消息类型值的存在可以实现基于优先级的消息队列,同时也可以实现区分不同使用目的消息的作用

 

  • flag
msgrcv 函数的 flag 参数取值
取值意义
MSG_NOERROR如果消息大于缓冲区,则被截断并正确返回,如果没有设置 MSG_NOERROR 则函数返回 E2BIG 错误信息
IPC_NOWAIT操作不阻塞,如果队列为空则直接返回 -1,errno 设置为 ENOMSG,如果没有设置 IPC_NOWAIT 则等待直到队列中有数据写入(如果在等待过程中队列被删除,则返回 EINTR)

 






读书笔记      技术帖      龙潭书斋      apue      unix环境高级编程      进程间通信      进程      ipc      消息队列      message queue      xsi      queue      msg      msqid_ds      msgget      msgctl      msgsend      垃圾桶函数      msgrcv     


京ICP备15018585号