posix 消息队列
注意
在涉及到posix消息的函数时, gcc 编译时要加-lrt参数, 如
gcc -lrt unpipc.c mqpack.c send.c -o send
gcc -lrt unpipc.c mqpack.c receive.c -o receive
posix消息的name必须以/开头, 例
./send /msgname
基本函数
#include <mqueue.h>
mqd_t mq_open(const char *name,int oflag, ...
/* mode_t mode, struct mq_attr *attr */);
int mq_close(mqd_t mqdes);
int mq_unlink(const char *name);
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr);
int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio);
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_t len, unsigned int *priop);
int mq_notify(mqd_t mqdes, const struct sigevent *notification);
#include <signal.h>
int sigwait(const sigset_t *set, int *sig);
posix消息队列的读写可以想像成文件的读写:
mq_close用于关闭mqd/关闭文件fd
mq_unlink用于删除消息队列/删除文件
mq_send发送消息到消息队列/写入文件
mq_receive从消息队列中取出消息/读取文件
mq_getattr获取消息属性/获取文件信息
mq_notify当队列中的消息数量由0到1时产生指定的信号/IO同步
mq_notify:
1.任意时候只有一个进程可以被注册为接收通知
2.当通知被发送到注册进程时,其注册即被撤销,就像老式的signal一样
3.当消息到达队列后再进行注册的话,不会产生消息
4.只有在消息队列的数量从0到1时才产生
sigwait:
1.sigwait是与当前进行的屏蔽信号函数sigprocmask搭配使用的
2.sigwait挂起线程,直到有感兴趣的信号到达,而这个信号也属于当前进程的屏蔽信号集
3.sigwait将信号从未决信号中删除,且不会调用信号处理函数,第二个参数返回该信号值
4.与sigsuspend不同的是,sigwait并不改变当前进程的信号屏蔽集,也不调用处理函数
包裹函数
mqpack.h
#ifndef _MQPACK_H
#define _MQPACK_H
#include "unpipc.h"
#include <mqueue.h>
mqd_t Mq_open(const char *name,int oflag,mode_t mode,struct mq_attr *attr);
void Mq_close(mqd_t mqd);
void Mq_unlink(const char *name);
void Mq_getattr(mqd_t mqd,struct mq_attr *attr);
void Mq_setattr(mqd_t mqd,struct mq_attr *attr,struct mq_attr *oattr);
void Mq_send(mqd_t mqd,const char *ptr,size_t len,unsigned int prio);
ssize_t Mq_receive(mqd_t mqd,char *ptr,size_t len,unsigned int *priop);
void Mq_notify(mqd_t mqd,const struct sigevent *notification);
#endif
mqpack.c
#include "mqpack.h"
mqd_t Mq_open(const char *name,int oflag,mode_t mode,struct mq_attr *attr){
mqd_t mqd=mq_open(name,oflag,mode,attr);
if(mqd == -1)
err_quit("mq_open error");
return(mqd);
}
void Mq_close(mqd_t mqd){
if(mq_close(mqd) == -1)
err_quit("mq_close error");
}
void Mq_unlink(const char *name){
if(mq_unlink(name) == -1)
err_quit("mq_unlink error");
}
void Mq_getattr(mqd_t mqd,struct mq_attr *attr){
if(mq_getattr(mqd,attr) == -1)
err_quit("mq_getattr error");
}
void Mq_setattr(mqd_t mqd,struct mq_attr *attr,struct mq_attr *oattr){
if(mq_setattr(mqd,attr,oattr) == -1)
err_quit("Mq_setattr error");
}
void Mq_send(mqd_t mqd,const char *ptr,size_t len,unsigned int prio){
if(mq_send(mqd,ptr,len,prio) == -1)
err_quit("mq_send error");
}
ssize_t Mq_receive(mqd_t mqd,char *ptr,size_t len,unsigned int *priop){
size_t n=mq_receive(mqd,ptr,len,priop);
if((-1 == n) && (errno != EAGAIN))
err_quit("mq_receive error");
return (n);
}
void Mq_notify(mqd_t mqd,const struct sigevent *notification){
if(mq_notify(mqd,notification) == -1)
err_quit("mq_notify error");
}
例子
编译和执行步骤就是文章开头的那三条命令
send.c
#include "unpipc.h"
#include "mqpack.h"
int main(int argc,char *argv[]){
if(argc != 2)
err_quit("usage: /send <name>");
char buff[1024];
mqd_t mqd;
struct mq_attr attr;
mqd=Mq_open(argv[1],O_WRONLY|O_CREAT,0644,NULL);
if(Fork() == 0){
if(execl("./receive","./receive",argv[1],(char *)0) == -1)
err_quit("execl error");
}
sleep(2);
while(1){
Fgets(buff,1024,stdin);
if(buff[strlen(buff)-1] == '\n') //去掉buff中的换行符
buff[strlen(buff)-1]='\0';
Mq_send(mqd,buff,strlen(buff),0);
}
Mq_close(mqd);
exit(0);
}
receive.c
#include "unpipc.h"
#include "mqpack.h"
void print_info(mqd_t mqd,struct mq_attr *attr){
if(mq_getattr(mqd,attr) == -1)
err_quit("mq_getn error");
printf("max num of maxmsg = %ld,max size of msg = %ld\n",attr->mq_maxmsg,attr->mq_msgsize);
printf("current mum of maxmsg = %ld\n",attr->mq_curmsgs);
}
int main(int argc,char *argv[]){
int signo;
mqd_t mqd;
void *buff;
ssize_t n;
sigset_t newmask;
struct mq_attr attr;
struct sigevent sigev;
if(argc != 2)
err_quit("usage mqtest2 <name>");
mqd=Mq_open(argv[1],O_RDONLY|O_NONBLOCK,0,NULL);
Mq_getattr(mqd,&attr);
buff=Malloc(attr.mq_msgsize);
print_info(mqd,&attr);
Sigemptyset(&newmask);
Sigaddset(&newmask,SIGUSR1);
Sigprocmask(SIG_BLOCK,&newmask,NULL);
sigev.sigev_notify=SIGEV_SIGNAL;
sigev.sigev_signo=SIGUSR1;
Mq_notify(mqd,&sigev);
for(;;){
Sigwait(&newmask,&signo);
if(signo == SIGUSR1){
Mq_notify(mqd,&sigev);
while((n=Mq_receive(mqd,buff,attr.mq_msgsize,NULL))>0)
printf("read %ld bytes\n",(long)n);
//if(errno != EAGAIN)
// err_quit("mq_receive error");
}
}
}
posix 消息队列的更多相关文章
- Linux IPC POSIX 消息队列
模型: #include<mqueue.h> #include <sys/stat.h> #include <fcntl.h> mq_open() //创建/获取消 ...
- Posix消息队列
转载于:http://blog.csdn.net/zx714311728/article/details/53197196 1.消息队列 消息队列可以认为是一个消息链表,消息队列是随内核持续的.队列中 ...
- 第5章 Posix 消息队列
5.1 概述 消息队列可以认为是一个链表.有写权限的线程可往消息队列中放置消息,有读权限的线程可以从消息队列中取走消息. 消息队列和管道/FIFO的区别: (1)消息队列往一个队列中写消息前,并不需要 ...
- Posix消息队列实现机制
本文是对<Unix 网络编程 卷2:进程通信>的笔记. 引言 消息队列是进程间通信的一种方式,可是如果不理解他的实现原理,会有众多不理解之处,下面就结合本书中的例子,对posix消息队列来 ...
- POSIX 消息队列相关问题
一.查看和删除消息队列要想看到创建的posix消息队列,需要在root用户下执行以下操作:# mkdir /dev/mqueue# mount -t mqueue none /dev/mqueue删除 ...
- Linux IPC实践(7) --Posix消息队列
1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...
- 进程间通信--POSIX消息队列
相关函数: mqd_t mq_open(const char *name, int oflag); mqd_t mq_send(mqd_t mqdes, const char *msg_ptr, si ...
- POSIX 消息队列 之 概述 链接方式
NAMEmq_overview —— POSIX消息队列概述 DESCRIPTIONPOSIX消息队列允许进程以消息的形式交换数据.此API与System V消息队列(msgget(2),msgsnd ...
- Unix IPC之Posix消息队列(1)
部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/ar ...
随机推荐
- uva 10252 - Common Permutation 字符串水题
题意:給定兩個小寫的字串a與b,請印出皆出現在兩字串中的字母,出現的字母由a~z的順序印出,若同字母出現不只一次,請重複印出但不能超過任一字串中出現的次數.(from Ruby兔) 很水,直接比较输出 ...
- Java 多线程-上课总结
Java 多线程 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启 ...
- cordova在app内部指定浏览器打开链接插件:cordova-plugin-inappbrowser
原文网址:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/cordova-plugin-inappbrowser/ 要想App里边的 ...
- phpQuery用法
了解phpQuery使用前了温习jquery.js的选择用法 jquery选择器,还有一个衍生产品QueryList 例: include 'phpQuery.php'; phpQuery::newD ...
- 七. CSS字体
概述 所谓字体:即文字的形体结构,根据外观字体分不同的类别:衬线字体Serif.无衬线字体sans-serif和等宽字体monospace.每一个类别的字体又可以分成不同的字体族font family ...
- 将java项目打包成jar文件并在cmd运行
保证java项目不报错能够通过运行 选择export 选择一个你要运行的程序入口Main方法 打开cmd,前提是你的javajdk及环境变量配置完成
- jquery更改Reaper某一列的值
一.实现效果:通过Jquery实现点击repeater中的按钮循环修改快递专线的线路状态 1.初始效果图 2.点击关闭专线按钮之后的效果图 二.MVC模式实现上述效果 SQLServerDAL层 #r ...
- 正确使用Android性能分析工具——TraceView
http://blog.jobbole.com/78995/ 首页 最新文章 IT 职场 前端 后端 移动端 数据库 运维 其他技术 - 导航条 - 首页 最新文章 IT 职场 前端 - Ja ...
- 批处理脚本修改hosts文件指定域名解析IP
现在很多网站都是前后台分开部署的,这样做是相对安全的.就算黑客拿到了前台shell也找不到后台的管理地址,增加安全性. 大家应该知道hosts文件的功能吧,用户在访问网站的时候 需要把域名解析成IP地 ...
- php读取目录下的文件
工作需要写了一个读取指定目录下的文件,并显示列表,点击之后读取文件中的内容 高手拍砖,目录可以自由指定,我这里直接写的是获取当前文件目录下面的所有文件 <?php /** * 读取指定目录下面的 ...