POSIX 消息队列基础知识复习,以及相关例程
1.1????????Posix消息隊(duì)列
1.1.1???????消息隊(duì)列的創(chuàng)建和刪除
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 )
創(chuàng)建或獲取一個(gè)消息隊(duì)列。成功返回消息隊(duì)列描述符;失敗返回-1。
參數(shù)name指定與消息隊(duì)列相關(guān)聯(lián)的名字。
參數(shù)flags可以取:
O_RDONLY???? O_WRONLY????? O_RDWR(三選一)
O_CREAT
單獨(dú)使用O_CREAT,如果不存在與name相關(guān)聯(lián)的消息隊(duì)列,就創(chuàng)建一個(gè)新的消息隊(duì)列,并返回其描述符,如果已經(jīng)存在與name相關(guān)聯(lián)的消息隊(duì)列,就返回該消息隊(duì)列的描述符。
如果指定了O_CREAT,需要使用mq_open( )的第二種形式,其中參數(shù)mode指定了新創(chuàng)建消息隊(duì)列的訪問(wèn)權(quán)限,參數(shù)attr指定了新創(chuàng)建消息隊(duì)列的屬性。
O_EXCL。
單獨(dú)使用O_EXCL是沒(méi)有意義的,如果O_EXCL和O_CREAT一起使用,當(dāng)與name相關(guān)聯(lián)的消息隊(duì)列已經(jīng)存在時(shí),就失敗返回。
O_NONBLOCK
決定在mq_send( )和mq_receive( )時(shí)是否會(huì)掛起當(dāng)前進(jìn)程,直到讀取或發(fā)送消息成功。
1.1.1.2????? mq_close( )
#include <mqueue.h>
int mq_close( mqd_t mqdes )
關(guān)閉當(dāng)前進(jìn)程和指定消息隊(duì)列之間的聯(lián)系。
成功返回0,失敗返回-1。
1.1.1.3????? mq_unlink( )
#include <mqueue.h>
int mq_unlink( const char *name )
刪除指定的消息隊(duì)列,但是如果當(dāng)前仍有其它進(jìn)程正在使用消息隊(duì)列,則暫時(shí)放棄刪除操作,并立即返回,直到其它進(jìn)程通過(guò)調(diào)用mq_close( )關(guān)閉之后,再進(jìn)行刪除操作。
成功返回0,失敗返回-1。
1.1.2???????消息隊(duì)列的屬性
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)
注意:只能設(shè)定mq_attr結(jié)構(gòu)中的mq_flags,mq_attr結(jié)構(gòu)中的其它成員將被忽略。
成功返回0,失敗返回-1。
1.1.3???????消息隊(duì)列的操作
1.1.3.1?????mq_notify()
#include<mqueue.h>
int mq_notify( mqd_t mqdes, const struct sigevent*notification )
成功返回0,失敗返回-1。
為當(dāng)前進(jìn)程在指定的消息隊(duì)列上注冊(cè)notify操作,當(dāng)消息隊(duì)列由空變?yōu)榉强諘r(shí),也就是說(shuō)有消息加入原本為空的消息隊(duì)列時(shí),會(huì)觸發(fā)進(jìn)程注冊(cè)的nofity操作。
參數(shù)notification指定需要注冊(cè)的nofity操作。如果參數(shù)notification為NULL,而且進(jìn)程之前注冊(cè)過(guò)notify操作,會(huì)取消之前注冊(cè)的notify操作。
需要注意的是:
1.只能有唯一的一個(gè)進(jìn)程在消息隊(duì)列上注冊(cè)notify操作。如果已經(jīng)有其它進(jìn)程在消息隊(duì)列上注冊(cè)了notify操作,試圖再次進(jìn)行notify()會(huì)失敗返回;
2.當(dāng)進(jìn)程注冊(cè)的nofity操作被觸發(fā)之后,該nofity操作就會(huì)被刪除,其它進(jìn)程可以重新向該消息隊(duì)列注冊(cè)notify操作。
如果進(jìn)程已經(jīng)注冊(cè)過(guò)notify操作,而且進(jìn)程在消息隊(duì)列為空時(shí),阻塞調(diào)用了mq_receive( )(即在mq_open()時(shí)設(shè)定了O_NONBLOCK),如果有一個(gè)消息到達(dá),會(huì)先滿足mq_receive( )調(diào)用,所以消息隊(duì)列仍然為空,不會(huì)觸發(fā)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。
參數(shù)len指定讀取消息的長(zhǎng)度,如果len<attr(mq_msgsize),失敗返回。
mq_open( )是否設(shè)定O_NONBLOCK,會(huì)決定mq_receive( )是否進(jìn)行阻塞讀取。
成功返回讀取消息的字節(jié)數(shù),失敗返回-1。
1.2.3.3?????mq_send( )
#include<mqueue.h>
intmq_send( mqd_t mqdes, const char *msg, size_t len, unsigned int prio )
參數(shù)len指定發(fā)送消息的長(zhǎng)度,如果len>attr(mq_msgsize),失敗返回。
參數(shù)prio<MQ_PRIO_MAX。
mq_open( )是否設(shè)定O_NONBLOCK,會(huì)決定mq_send( )是否進(jìn)行阻塞發(fā)送。
成功返回0,失敗返回-1。
?
2.1? Code
2.1.1 創(chuàng)建一個(gè)消息隊(duì)列
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 發(fā)送消息
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 Code2.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?
轉(zhuǎn)載于:https://www.cnblogs.com/shaosli/p/5103054.html
總結(jié)
以上是生活随笔為你收集整理的POSIX 消息队列基础知识复习,以及相关例程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ubuntu各版本代号(更新至15.04
- 下一篇: apache开源项目--ZooKeepe