消息队列中的每个消息都有如下的数据结构:
struct msgbuf
{
long mtype; // 消息类型
char mtext[n]; // 消息内容,n由用户自己定义
};
#include<sys/types.h>
#include<sys/ipc.h>
key_tftok( const char *name, int id )
参数name指定了文件名(包含路径),该文件必须存在,而且当前进程必须能够访问该文件。
参数id只有低8位有效。
只有当name和id取值都相同时,返回的键值key才是相同的。
成功返回键值,失败返回-1。
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
intmsgget( key_t key, int msgflg )
创建或获取消息队列;成功返回与key相关联的消息队列id,失败返回-1。
参数msgflg可以取IPC_CREAT、IPC_EXCL、IPC_NOWAIT。
单独使用IPC_CREAT,如果不存在与键值key相关联的消息队列,就创建一个新的消息队列,并返回其id,如果已经存在与键值key相关联的消息队列,就返回该消息队列的id。
单独使用IPC_EXCL是没有意义的,如果IPC_EXCL和IPC_CREAT一起使用,当与键值key相关联的消息队列已经存在时,就失败返回-1。
下面两种情况会创建一个新的消息队列:
1.参数msgflg指定IPC_CREAT,而且没有消息队列与键值key相关联;
2.参数key指定IPC_PRIVATE;
参数msgflg的低9位指定新创建消息队列的访问权限:
所有者 |
组成员 |
其他成员 |
||||||
读 |
写 |
执行 |
读 |
写 |
执行 |
读 |
写 |
执行 |
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
ssize_tmsgrcv( int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg );
读取消息队列中的一个消息,存放到msgp指向的msgbuf结构中。
成功返回实际读出消息内容的字节数,并将消息从消息队列中移除;失败返回-1,不移除消息。
msgsz指定读取消息的长度,即msgbuf结构中mtext[n]的长度。
msgtyp指定读取消息的类型:
msgtyp = 0 读取消息队列中的第一个消息
msgtyp>0 读取消息队列中第一个msgtyp类型的消息,如果没有,失败返回
msgtyp<0 如果消息队列中的最小类型≤abs(msgtyp),读取最小类型的第一个消息;
如果消息队列中的最小类型>abs(msgtyp),失败返回
参数msgflg可以取值:
IPC_EXCEPT :当msgtyp>0时,返回消息队列中第一个类型不是msgtyp的消息。
IPC_NOWAIT
设定 :如果消息队列中没有满足条件的消息,立即失败返回。
未设定 ;如果消息队列中没有满足条件的消息,挂起当前进程,直到以下任一事件发生:
1.满足条件的消息出现在消息队列中,成功返回;
2.消息队列被删除,失败返回。
IPC_NOERROR
设定 :如果消息内容>msgsz,把多余的消息内容清除,成功返回。
未设定 :如果消息长度>msgsz,失败返回。
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
intmsgsnd( int msqid, struct msgbuf *msgp, int msgsz, int msgflg );
向消息队列中发送一个消息,消息来源是msgp指向的msgbuf结构。
成功返回0;失败返回-1。
msgsz指定发送消息的长度,即msgbuf结构中mtext[n]的长度。
参数msgflg可以取值:
IPC_NOWAIT
设定 :如果队列中的消息内容或消息数目已经达到上限,立即失败返回。
未设定 :如果队列中的消息内容或消息数目已经达到上限,挂起当前进程直到任一事件发生:
1.消息内容或消息数目恢复正常,成功返回;
2.消息队列被删除,失败返回。
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
intmsgctl( int msqid, int cmd, struct msqid_ds *buf );
获取或设置消息队列的属性,成功返回0;失败返回-1。
参数cmd可以指定三种操作:
IPC_RMID :删除指定的消息队列。
IPC_STAT :用来获取消息队列的信息,返回的信息存放到buf指向的msqid_ds结构中。
IPC_SET :用来设置消息队列的属性,要设置的属性存储在buf指向的msqid_ds结构中。
#include<mqueue.h>
mqd_tmq_open( const char *name, int flag )
mqd_t mq_open( const char *name, int flag, mode_t mode, mq_attrattr )
创建或获取一个消息队列。成功返回消息队列描述符;失败返回-1。
参数name指定与消息队列相关联的名字。
参数flags可以取:
O_RDONLY O_WRONLY O_RDWR(三选一)
O_CREAT
单独使用O_CREAT,如果不存在与name相关联的消息队列,就创建一个新的消息队列,并返回其描述符,如果已经存在与name相关联的消息队列,就返回该消息队列的描述符。
如果指定了O_CREAT,需要使用mq_open( )的第二种形式,其中参数mode指定了新创建消息队列的访问权限,参数attr指定了新创建消息队列的属性。
O_EXCL。
单独使用O_EXCL是没有意义的,如果O_EXCL和O_CREAT一起使用,当与name相关联的消息队列已经存在时,就失败返回。
O_NONBLOCK
决定在mq_send( )和mq_receive( )时是否会挂起当前进程,直到读取或发送消息成功。
#include <mqueue.h>
int mq_close( mqd_t mqdes )
关闭当前进程和指定消息队列之间的联系。
成功返回0,失败返回-1。
#include <mqueue.h>
int mq_unlink( const char *name )
删除指定的消息队列,但是如果当前仍有其它进程正在使用消息队列,则暂时放弃删除操作,并立即返回,直到其它进程通过调用mq_close( )关闭之后,再进行删除操作。
成功返回0,失败返回-1。
#include<mqueue.h>
intmq_getattr( mqd_t mqdes, struct mq_attr *attr )
成功返回0,失败返回-1。
struct mq_attr
{
long mq_flags; //message queue flags
long mq_maxmsg; //maximum number of messages
long mq_msgsize; // maximummessage size
long mq_curmsgs; // numberof messages currently queued
}
#include<mqueue.h>
intmq_setattr( mqd_t mqdes, const struct mq_attr *newAttr, struct mq_attr *oldAttr)
注意:只能设定mq_attr结构中的mq_flags,mq_attr结构中的其它成员将被忽略。
成功返回0,失败返回-1。
#include<mqueue.h>
int mq_notify( mqd_t mqdes, const struct sigevent*notification )
成功返回0,失败返回-1。
为当前进程在指定的消息队列上注册notify操作,当消息队列由空变为非空时,也就是说有消息加入原本为空的消息队列时,会触发进程注册的nofity操作。
参数notification指定需要注册的nofity操作。如果参数notification为NULL,而且进程之前注册过notify操作,会取消之前注册的notify操作。
需要注意的是:
1.只能有唯一的一个进程在消息队列上注册notify操作。如果已经有其它进程在消息队列上注册了notify操作,试图再次进行notify()会失败返回;
2.当进程注册的nofity操作被触发之后,该nofity操作就会被删除,其它进程可以重新向该消息队列注册notify操作。
如果进程已经注册过notify操作,而且进程在消息队列为空时,阻塞调用了mq_receive( )(即在mq_open()时设定了O_NONBLOCK),如果有一个消息到达,会先满足mq_receive( )调用,所以消息队列仍然为空,不会触发notify操作。
struct sigevent
{
int sigev_notify;
int sigev_signo; // signal numbersent to current process when the timer expires
union sigval sigev_value; // info carried with signal
NotifyFUN sigev_notify_function; //typedef void (*NotifyFUN)( union sigval)
pthread_attr_t* sigev_notify_attributes;
}
sigev_notify的取值:
SIGEV_NONE :No notification will be delivered when the event ofinterest occurs.
SIGEV_SIGNAL :A queued signal will be generated when theevent of interest occurs.
SIGEV_THREAD :A notification function will be called toperform notification.
#include<mqueue.h>
ssize_tmq_receive( mqd_t mqdes, char *msg, size_t len, unsigned int *prio )
读取the oldest of the highest priority message。
参数len指定读取消息的长度,如果len<attr(mq_msgsize),失败返回。
mq_open( )是否设定O_NONBLOCK,会决定mq_receive( )是否进行阻塞读取。
成功返回读取消息的字节数,失败返回-1。
#include<mqueue.h>
intmq_send( mqd_t mqdes, const char *msg, size_t len, unsigned int prio )
参数len指定发送消息的长度,如果len>attr(mq_msgsize),失败返回。
参数prio<MQ_PRIO_MAX。
mq_open( )是否设定O_NONBLOCK,会决定mq_send( )是否进行阻塞发送。
成功返回0,失败返回-1。