1.1 Posix消息队列
1.1.1 消息队列的创建和删除
1.1.1.1 mq_open( )
#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( )时是否会挂起当前进程,直到读取或发送消息成功。
1.1.1.2 mq_close( )
#include <mqueue.h>
int mq_close( mqd_t mqdes )
关闭当前进程和指定消息队列之间的联系。
成功返回0,失败返回-1。
1.1.1.3 mq_unlink( )
#include <mqueue.h>
int mq_unlink( const char *name )
删除指定的消息队列,但是如果当前仍有其它进程正在使用消息队列,则暂时放弃删除操作,并立即返回,直到其它进程通过调用mq_close( )关闭之后,再进行删除操作。
成功返回0,失败返回-1。
1.1.2 消息队列的属性
1.1.2.1 mq_getattr( )
#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
}
1.1.2.2 mq_setattr( )
#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。
1.1.3 消息队列的操作
1.1.3.1 mq_notify()
#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.
1.2.3.2 mq_receive( )
#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。
1.2.3.3 mq_send( )
#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。
2.1 Code
2.1.1 创建一个消息队列
1 /* 2 @Author: shaosli 3 @data: 2016/1/5 4 @function: test create mq of posxi 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <mqueue.h> 11 #include <fcntl.h> 12 #include <errno.h> 13 #include <sys/stat.h> 14 15 int main( int argc, char* argv[]) 16 { 17 18 mqd_t mqd; 19 struct mq_attr attr; 20 int flags = O_RDWR | O_CREAT | O_EXCL; 21 char *pdName = "/mqu"; 22 printf("create mqueue.\n"); 23 //create a new queue. 24 if( mqd = mq_open(pdName, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, NULL) == -1) 25 { 26 perror("open failure."); 27 exit(-1); 28 } 29 30 mq_getattr(mqd, &attr); 31 printf("max msgs = %ld, mq_msgsize = %ld,mq_curmsgs = %ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs); 32 mq_close(0); 33 return 0; 34 }
2.1.2 发送消息
1 /* 2 @Author: shaosli 3 @data: 2016/1/5 4 @function: test send mq of posxi 5 */ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 #include <mqueue.h> 10 #include <fcntl.h> 11 #include <errno.h> 12 #include <sys/stat.h> 13 14 int main() 15 { 16 mqd_t mqd; 17 char *pdName = "/mqu"; 18 char* ptr = "hi"; 19 mqd = mq_open(pdName, O_WRONLY); 20 21 if( mq_send(mqd, ptr, 10, 10) == -1) 22 { 23 perror("mq_send(),error."); 24 exit(-1); 25 } 26 27 return 0; 28 }
2.1.3 接受消息
1 /* 2 @Author: shaosli 3 @data: 2016/1/5 4 @function: test receive mq of posxi 5 */ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <unistd.h> 9 #include <mqueue.h> 10 #include <fcntl.h> 11 #include <errno.h> 12 #include <sys/stat.h> 13 14 int main() 15 { 16 mqd_t mqd; 17 int priot, n; 18 struct mq_attr attr; 19 char *pdName = "/mqu"; 20 mqd = mq_open(pdName, O_RDONLY); 21 22 mq_getattr(mqd, &attr); 23 char *buf = malloc(10); 24 25 if( (n = mq_receive(mqd, buf, attr.mq_msgsize, &priot)) == -1) 26 { 27 perror("mq_receive(),error."); 28 exit(-1); 29 } 30 printf("priot = %d, recbuf=%s, attr.mq_msgsize =%ld", priot, buf,attr.mq_msgsize); 31 32 return 0; 33 }