消息队列
之前我们解析了一下进程间通信的管道通信,今天我们来看一下另外俩种通信方式:消息队列和共享内存。
那什么是消息队列呢?之前我们说管道在进程间通信的时候是基于字节流的,而消息队列在进程间通信的时候是基于数据块的,
并且是有类型的数据块。消息队列提供了一个从一个进程向另外一个进程发送一个有不同类型值的数据块的方法。
每个消息队列都有一个msqid_ds 结构与其相关联,在/usr/include/linux/msg.h 中可以查到:
此结构定义了队列的当前状态,其中第一个成员 struct ipc_perm 是IPC对象数据结构,内核为每一个IPC对象维护一个数据结构。这个
在/usr/include/linux/ipc.h 中也可以查到:
接下来我们看一下消息队列相关函数:
msgget函数
功能:用来创建和访问一个消息队列
函数原型:int msgget(key_t key,int msgflg);
参数:
key:某个消息队列的名字,可通过ftok函数获得,为了确保进程间通信,我们必须保证俩个进程的key值相同。
#include<sys/ipc.h>
key_t ftok(const char *path,int id);
path参数必须引用一个现有的文件。
msgflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的,最常用的两个是
IPC_CREAT,IPC_EXCL。如果希望创建一个新的消息队列,那么必须在flag中同时指定IPC_CREAT和IPC_EXCL位,如果
消息队列已经存在就会造成出错。如果在flag中单独指定IPC_CREAT位,消息队列不存在就创建,存在就返回不会报错。
返回值:成功返回一个非负整数,即该消息队列的标识码;失败返回-1.
msgctl函数:
功能:消息队列的控制
函数原型:int msgctl(int msqid,int cmd,struct msqid_ds *buf);
参数:
msqid:由msgget函数返回的消息队列标识码
cmd:是将要采取的动作,(有三个可取值,在下文中会说明)
返回值:成功返回0,失败返回-1
cmd将要采取的三个动作:
IPC_STAT:该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID:从内核中删除 msqid 标识的消息队列。
msgsnd函数:
功能:把一条消息添加到消息队列中
函数原型:int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflag);
返回值:成功返回0;失败返回-1
msgrcv函数:
功能:从一个消息队列接受消息
原型:ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
返回值:成功返回实际放到接收缓冲区里的字符个数,失败返回-1
这俩个函数的参数比较想象,我们放在一起说:
msqid:由msgget函数返回的消息队列标识码
msgq:是一个指针,指向准备发送(接收)的消息。消息结构参考形式如下:
struct msgbuf{
long type;//进程间发送数据块的类型值
char text[1];//