码迷,mamicode.com
首页 > 其他好文 > 详细

POSIX 消息队列基础知识复习,以及相关例程

时间:2016-01-05 18:35:02      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

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 }
View Code

 

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 }
View Code

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 }
View Code

 

POSIX 消息队列基础知识复习,以及相关例程

标签:

原文地址:http://www.cnblogs.com/shaosli/p/5103054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!