今天来介绍IPC通信的第一种方式:消息对列
由于进程具有独立性,要想两个进程之间有数据的往来,就必须让两个不相干的进程看到同一块资源。前面有讲到管道,也是一种公共资源。现在,我们介绍一种另一种公共资源:消息对列
消息对列,顾名思义,想必看到的公共资源可能就是一种队列。这种队列满足数据结构里队列的特点:先进先出。
消息对列提供了一个进程向另一个进程发送一块数据快的通信方法,注意,是以块为基本单位,前面的管道是以字节流为基本单位。
每个数据块都被认为是由类型的。接收者进程接受数据块可以有不同的类型值,比如可以是结构体型。
每个消息 队列的最大长度是上限的(MSGMAX),每个消息队列的总的字节数也是有上限的(MSGMNB),系统的消息队列总数也是有上线的(MSGMNI),
认识消息队列结构
查看命令:
[zyc@localhost /]$ cat ./usr/include/linux/ipc.h
[zyc@localhost /]$ cat ./usr/include/linux/msg.h
msgget函数
功能:创建和访问消息队列
原型:
#include
#include
#include
int msgget(key_t key, int msgflg);
参数:
key:某个消息队列的名字
msgflg:有九个权限标识位组成,他们的用法和创建文件时使用的mode模式是一样的
返回值:
成功返回一个非负整数,即该消息队列的识别码,即msgid,给用户看。失败返回-1
这里解释一下标识位
IPC_CREAT:如果文件不存在,则创建一个新文件,如果存在,把存在的文件描述符返回
IPC_EXCL:没有任何实际意义,只在创建时使用,与IPC_CREAT进行或运算:IPC_CREAT|EXCL,则会创建一个全新的文件。
再解释一下 key,通过“ftok”函数获得。函数调用成功时,即通过它,就可以找到消息对列。
下面来看ftok函数介绍
#include
#include
key_t ftok(const char *pathname, int proj_id);
作用:获得消息对列标识符。两个互相独立的进程要进行通信,就必须都可以看到这个标志符。进程A和进程B都可以看到。
参数自己定制,一般定义在头文件中,采用宏定义方式。一般路径采用当前路径,proj_id设置0x666
返回值:成功返回消息对列标志符(给内核看),失败返回-1。
msgctl函数
作用:消息对列的控制函数
原型:
#include
#include
#include
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数
msqid:msgget函数的返回值,即消息队列识别码
cmd:有三个动作
返回值
成功返回0,失败返回-1;
cmd的三个动作:
命令 | 说明 | |
---|---|---|
IPC_STST | ||
IPC_SET | ||
IPC_RMID | 删除消息队列 |
msgsend函数
功能:把一条消息加入消息对列中
原型
#include
#include
#include
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
msgid:由msgget函数返回的消息对列标志码
msgp:,是一个指针指向即将发送的消息
msgsz:是msgp指向的消息队列长度
msgflg:控制着当前消息对列到达系统上限即将发生的事情。
msgflg==IPC+NOWAIT表示对列不等待。返回EAGAIN错误。
返回值:成功返回0,失败返回-1;
1:消息结构在两方面受到制约:
msgrcv函数
功能:从一个消息队列中接收消息
#include
#include
#include
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
msgid:由msgget函数返回的消息对列标志码
msgp:,是一个指针指向即将发送的消息
msgsz:是msgp指向的消息队列长度
msgtype:他可以实现接收优先级的简单形式
msgflg:控制着消息队列中没有相应类型消息可供接收时将要发生的事情。
返回值:
成功返回0,失败返回-1;
mytype=0:返回队列第一条消息
mytype>0:返回队列第一条类型等于中mytype的消息
mytype<0:返回队列中第一条类型小于mytype绝对值的消息,并且是满足条件的消息类型最小消息。
mytype=IPC_NOWAIT,队列没有消息不等待,返回ENOMSG错误
mytype=MSG_MOERROR,消息超过msgsize是将会被截断。
mytype>0且msgflg=MSG_EXCEPT,接受类型不等于msgtype的第一条消息。
下面我们将要来编写实际代码来实现基于消息对列的进程间通信。
ipcs 显示IPC资源
ipcs -q :查看已存在消息对列
ipcrm -q (msgid) :删除指定消息对列