POSIX消息队列(mq_)

来源:互联网 发布:电影票房数据 编辑:程序博客网 时间:2024/06/09 20:25

头文件:

mqueue.h

库:

rt--------librt.so

编译的时候加-lrt

查看POSIX消息队列所有函数:

man mq_overview

结构体:

struct mq_attr{

mq_flags;

——标志:

————在mq_open创建时被初始化;

————在mq_setattr中设置;

————其值为0(阻塞)或者O_NONBLOCK(非阻塞)。

mq_maxmsg;

——队列的消息个数最大值:

————只能在mq_open创建时被初始化。

mq_msgsize;

——队列中每个消息的最大值:

————只能在mq_open创建时被初始化。

mq_curmsgs:

——当前队列的消息个数:

————在mq_getattr中获得。

}

查看消息队列文件:

创建的消息队列在/dev/mqueue中存放。如果没有需要建立一个。

建立方法:

依次输入命令:

mkdir  /dev/mqueue //创建文件夹

mount -t mqueue none /dev/mqueue//挂载

函数:

创建消息队列:

mqd_t  mq_open(const char* name, int oflag, mode_t mode, struct mq_attr* attr);

参数:

name:

posix IPC名字。(必须以/开头,且后面不能再含有/)

oflag:

标志。

标志——————————作用
O_CREAT———————没有该对象则创建
O_EXCL————————如果O_CREAT指定,但name不存在,就返回错误
O_NONBLOCK—————以非阻塞方式打开消息队列
O_RDONLY———————只读
O_RDWR————————读写
O_WRONLY———————只写

mode:

权限——————作用
S_IWUSR——用户/属主写
S_IRUSR——用户/属主读
S_IWGRP——组成员写
S_IRGRP——组成员读
S_IWOTH——其他用户写
S_IROTH——其他用户读

attr:

队列属性。为上面所说的结构体。

返回值:

-1————出错

其他———消息队列描述符

代码:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <mqueue.h>#include <fcntl.h>#include <sys/stat.h>#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644int main(int argc,char* argv[]){int c,flag=0;long maxmsg = 10;long msglen = 8192;while((c=getopt(argc,argv,"q:l:"))!=-1){switch(c){case 'q':maxmsg = atoi(optarg);break;case 'l':msglen = atoi(optarg);break;}}if(optind != argc-1){printf("usage:%s [-q <maxmsg>] [-l <msglen>] <mqname>\n",argv[0]);return 1;}struct mq_attr attr;attr.mq_maxmsg = maxmsg;attr.mq_msgsize = msglen;mqd_t mqd = mq_open(argv[optind],O_CREAT,FILE_MODE,&attr);if(-1 == mqd){perror("mq_open error");return 1;}}


删除消息队列:

int mq_unlink(char* name);

参数:

name:

posix IPC名字。

返回值:

-1————出错

0————成功

代码:

#include <stdio.h>#include <stdlib.h>#include <mqueue.h>#include <fcntl.h>#include <sys/stat.h>int main(){mq_unlink("/tmp.test");}


打开消息队列:

mqd_t mq_open(const char* name, int oflag);

参数:

name:

posix IPC名字。

oflag:

标志。(同创建中的oflag)

返回值:

-1————出错

其他———描述符

关闭消息队列:

int mq_close(mqd_t mqdes);

参数:

mqdes:

消息队列描述符。

返回值:

-1——出错

0——成功

设置消息队列属性:

int mq_getattr(mqd_t mqdes, struct mq_attr* nemattr, mq_attr* oldattr);

参数:

mqdes:

消息队列描述符。

newattr:

新属性;

只能设置mq_flags(0(阻塞)或O_NONBLOCK(非阻塞))。

oldattr:

旧属性。

返回值:

-1——出错

0——成功

代码:

#include <stdio.h>#include <stdlib.h>#include <mqueue.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>int main(){mqd_t mqd = mq_open("/tmp.test",O_RDWR);if(-1 == mqd){perror("mq_open error");return;}struct mq_attr new_attr;bzero(&new_attr,sizeof(new_attr));//设置新属性new_attr.mq_flags = O_NONBLOCK;struct mq_attr attr;if(-1 == mq_setattr(mqd,&new_attr,&attr)){perror("mq_setattr error");return 1;}
//输出旧属性printf("flag:%ld,Max msg:%ld,Max msgsize:%ld,Cur msgnun:%ld\n",attr.mq_flags,attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);}


获取消息队列属性:

int mq_getattr(mqd_t mqdes, struct mq_attr* attr);

参数:

mqdes:

消息队列描述符。

attr:

属性。

返回值:

-1——出错

0——成功

代码:

#include <stdio.h>#include <stdlib.h>#include <mqueue.h>#include <fcntl.h>#include <sys/stat.h>int main(int argc,char* argv[]){mqd_t mqd = mq_open(argv[1],O_RDONLY);if(-1 == mqd){perror("mq_open error");return;}struct mq_attr attr;mq_getattr(mqd,&attr);printf("flag:%ld,Max msg:%ld,Max msgsize:%ld,Cur msgnun:%ld\n",attr.mq_flags,attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);}


发送消息:

int mq_send(mqd_t mqdes, const char* msg_ptr, size_t  msg_len,unsigned  msg_prio);

特点:

消息队列已满,mq_send()函数将阻塞,知道有可用空间再次允许放置消息。

如果O_NONBLOCK被指定,满队时mq_send()将不会阻塞,而是返回EAGAIN错误。

参数:

msg_ptr:

要发送消息的指针。

msg_len:

消息长度(不能大于属性值mq_msgsize的值)。

msg_prio:

优先级(消息在队列中将按照优先级从大到小的顺序排列消息;数字越大优先级越高)。

代码:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <mqueue.h>#include <fcntl.h>#include <string.h>#include <sys/stat.h>#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644int main(int argc,char* argv[]){int c,flags=O_WRONLY;while((c=getopt(argc,argv,"n"))!=-1){switch(c){case 'n':flags|=O_NONBLOCK;//增加标志属性,现在为只写+非阻塞break;}}if(optind != argc-3){printf("usage:%s [-n] <mqname> <message> <prio>\n");return 1;}mqd_t mqd = mq_open(argv[optind],flags);if(-1 == mqd){perror("mq_open error");return 1;}if(-1 == mq_send(mqd,argv[optind+1],strlen(argv[optind+1])+1,atoi(argv[optind+2]))){perror("mq_send error");return 1;}}


接收消息:

ssize_t mq_receive(mqd_t mqdes, char* msg_ptr, size_t msg_len,unsigned* msg_prio);

特点:

按优先级从高到低进行接收。即优先级值大的先接收。

如果队列为空,mq_receive()函数将阻塞,知道消息队列中有新的消息。

如果O_NONBLOCK被指定,mq_receive()将不会阻塞,而是返回EAGAIN错误。

参数:

msg_ptr:

要接收消息的指针。

msg_len:

接收消息的长度(不能大于属性值mq_msgsize的值)。

msg_prio:

接收到的优先级大小(消息在队列中将按照优先级从大到小的顺序排列消息;数字越大优先级越高)。

返回值:

-1————出错

正数———接收到的消息长度

代码:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <mqueue.h>#include <fcntl.h>#include <sys/stat.h>#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644int main(int argc,char* argv[]){int c,flags=O_RDONLY;while((c=getopt(argc,argv,"n"))!=-1){switch(c){case 'n':flags|=O_NONBLOCK;//增加标志属性,现在为只读|非阻塞break;}}if(optind != argc-1){printf("usage:%s [-n] <mqname>\n");return 1;}mqd_t mqd = mq_open(argv[optind],flags);if(-1 == mqd){perror("mq_open error");return 1;}char buf[BUFSIZ];int prio;if(-1 == mq_receive(mqd,buf,BUFSIZ,&prio)){perror("mq_send error");return 1;}printf("msg:%s\nprio:%d\n",buf,prio);}


原创粉丝点击