消息队列
消息队列提供了一种从⼀个进程向另⼀个进程发送⼀个数据块的方法。每个数据块都被认 为是有⼀个类型,接收者进程接收的数据块可以有不同的类型值。管道通信是基于字节流的通信,而消息队列发送的是一个数据结构,为IPC对象。
IPC对象
操作系统内核给每个IPC对象维护一个数据结构,生命周期随内核而销毁,管道的生命周期随进程。
struct ipc_perm{
key_t __key; //唯一标识IPC进程
uid_t uid; //拥有者
gid_t gid;
uid_t cuid; //创建者
gid_t cgid;
unsigned short mode; //权限
unsigned short __seq;
};
消息队列的创建
头文件:<sys/types.h>
<sys/msg.h>
<sys/ipc.h>
函数: int msgget (key_t key, int msgflg)
参数 key 是函数 key_t ftok (const char* pathname, int PROJ_ID)的返回值,其中pathname为路径,PROJ_ID为工程号。ftok()函数将一个已经存在的路径名和一个标识转化成key值
参数msgflg有两个值,分别是IPC_CREAT,和IPC_EXCL;
IPC_CREAT 单独使用时创建⼀一个IPC资源,当IPC资源存在时,获取已存在的资源。
IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。
IPC_CREAT和IPC_EXCL标志⼀起使用,msgget()将返回⼀一个新建的IPC标识符 ;如果该IPC资源已存在返回-1。保证 所得的对象是新建的,⽽而不是打开已有的对象。
消息队列的销毁
函数: int msgctl (int msg_id int cmd, struct msid_ds* buf)
参数:msgctl 系统调⽤用对 msgqid 标识的消息队列执⾏行 cmd 操作,系统定义了 3 种 cmd 操作 : IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 该命令⽤用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指 定的地址空间。
IPC_SET : 该命令⽤用来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。
发送消息队列
函数:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
参数msqid:消息队列的标识码
msgp:指向消息缓冲区的指针,来暂时存储发送和接收的消息,是⼀个⽤用户自定义的数据结构。
struct msgstru{
long mtype;
char mtext[大小可变]; };
char mtext[大小可变]; };
msgsz:消息的大小。
msgflg:当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取 阻塞等待的处理模式
接受消息队列
函数:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数 msgtyp:表示从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都 会被读取。
创建好IPC后如何查看系统中IPC信息呢?在linux中使用命令:ipcs -q 可以查看。
若要删除IPC资源时,有多种方法,可以关机,也可以使用命令 :ipcrm -q来删除该资源。