POSIX 消息队列 之 参数说明
消息队列
一、函数
mq_open
头文件
mqueue.h;
原型
mqd_t mq_open(const char *name, int oflag, .../*mode_t mode,struct mq_attr* attr*/);
函数功能
创建消息队列;
参数
name :消息队列的名字,根据消息队列的规则,为了更好的可移植性,该名字必须以‘/’开头,创建一个消息队列的时候无须路径,给出名字就好,其存放位置可有自己指定(创建前后都可以)。
oflag:O_RDONLY(只读) O_WRONLY(只写) O_RDWR(可读可写)O_CREAT(创建) O_EXCL (当消息已存在时,返回EEXIST错误到errno中)O_NONBLOCK(设置非阻塞)
mode:在oflag中指定O_CREAT时,此参数是需要的。表示创建消息队列的权限,S_IRUSR,S_IWUSR,S_IXUSR,S_IRGRP,S_IWGRP,S_IXGRP,S_IROTH,S_IWOTH,S_IXOTH相或组成或者写成0777(表示rwxrwxrwx)等用八进制表示也可以。
attr:在oflag中指定O_CREAT时,此参数是需要的。存放消息队列的属性。其中mq_flags为0,表示阻塞,为O_NONBLOCK为非阻塞。
(这里可以填写哪些参数具体看:二、Posix IPC)
返回值
若创建成功则返回消息队列的描述符,否则返回-1。
mq_close函数
头文件
mqueue.h
原型
int mq_close(mqd_t mqdes);
函数功能
关闭已打开的消息队列,关闭后调用进程不可以再使用该描述符,但其消息队列并没有被删除。一个进程终止时,它的所有打开着的消息队列都关闭,就像调用了mq_close一样。
参数
mqdes 消息队列的描述符,即消息队列创建成功后的返回值。
返回值
成功返回0,失败返回-1。
mq_unlink
头文件
mqueue.h
原型
int mq_unlink(const char *name);
函数功能
从系统中删除名为name的消息队列,但删除的只是我们可以在系统中看见的文件的名字,但文件本身并没有被从磁盘上删除,除非该名称是文件的最后一个链接,并且该文件已关闭,才会将该文件真正从磁盘上删除。即如果某前该详细队列的文件还在其他进程中打开,那么不会将其从磁盘上删除,又或者这是最后一个链接,但它还为关闭,即未执行ma_close操作,或打开它的进程为结束就执行mq_unlink,它也不会从磁盘上删除。
参数
name消息队列的名称,以‘/’开始。
返回值
成功返回0,出错返回-1。
mq_getattr
头文件
mqueue.h
原型
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
函数功能
获取mqdes指的消息队列的属性,存放到attr结构体中。
struct mq_attr
{
long int mq_flags; /* Message queue flags:0,O_NONBLOCK */
long int mq_maxmsg; /* Maximum number of messages. */
long int mq_msgsize; /* Maximum message size. */
long int mq_curmsgs; /* Number of messages currently queued. */
long int __pad[4];
};
参数
mqdes为消息队列描述符,attr为上面解释的存放消息队列属性的结构体。
返回值
成功返回0,失败返回-1。
mq_setattr
头文件
mqueue.h
原型
int mq_setattr(mqd_t mqdes, const struct mq_attr *attr,
struct mq_attr *oattr);
函数功能
设置消息队列的属性,但是只使用attr结构体中的mq_flags属性,以设置(O_NONBLOCK)或清除(0)非阻塞标志。该结构体的另外三个属性被忽略,每个队列的最大消息数和每个消息的最大字节数都只能在创建时设置,当前队列中的消息数是随传送消息和读取消息的操作改变的,只能读取不能设置。如果oattr非空,那么指定队列的先前属性(4个)全将返回到由该指针指向的结构体中。
参数
mqdes 消息队列的属性
attr 函数功能解释中
oattr 函数功能解释中
返回值
成功返回0,失败返回-1。
mq_send
头文件
mqueue.h
原型
int mq_send(mqd_t mqdes, const char *ptr, size_t len,
unsigned int prio);
函数功能
给描述符mqdes指向的消息队列发送消息,大小为len,内容存放在ptr中,prio为优先级。
参数
mqdes为要发送消息的消息队列描述符;
ptr为要发送的数据;
len为消息的长度;
prio为消息的优先级;
返回值
成功返回0,失败返回-1。
mq_receive
头文件
mqueue.h
原型
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_t len,
unsigned int *proip);
函数功能
从描述符mqdes指向的消息队列中读取消息存放ptr中。
参数
mqdes为要从中读取消息的消息队列的描述符;
ptr为存放接受到的消息的指针;
len为接受的最大长度;
该值不能小于能加到该消息对列上的最大大小,如果len小于该值,就立即返回EMSGSIZE错误。
返回值
成功返回读取消息的内容的字节数,出错返回-1。
mq_notify
头文件
mqueue.h;
signal.h;
原型
int mq_notify(mqd_t mqdes, const struct sigevent *notification);
函数功能
为指定队列建立或删除异步事件通知。
参数
在<signal.h>中:
union signal{ int sival_int; /*整数值*/ void *sival_ptr; /*指针值*/};struct sigevent{ int sigev_notify; /*通知类型:SIGEV_NONE、SIGEV_SIGNAL、SIGEV_THREAD*/ int sigev_signo; /*信号值*/ union sigval sigev_value; /*传递给信号处理函数或线程的信号值*/ void (*sigev_notify_function)(union sigval); /*线程处理函数*/ pthread_attr_t *sigev_notify_attributes; /*线程属性*/};(1).如果notification参数非空,那么当前进程希望在有一个消息到达所指定的先前为空的队列时得到通知。我们说“该进程被注册为接收该队列的通知”。
(2).如果notification参数为空指针,而且当前进程目前被注册为接收所指定队列的通知,那么已存在的注册将被撤销。
(3).任意时刻只有一个进程可以被注册为接收某个指定队列的通知。
(4).当有一个消息到达某个先前为空的队列,而且已有一个进程被注册为接收该队列的通知时,只有在没有任何线程阻塞在该队列的mq_receive调用中的前提下,通知才会发出。这就是说,在mq_receive调用中的阻塞比任何通知的注册都优先。
(5).当该通知被发送给它的注册进程时,其注册即被撤销。该进程必须再次调用mq_notify重新注册(如果想要的话)。
返回值
成功返回0,失败返回-1。
二、程序举例
mqsend.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<mqueue.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main(int argc, char **argv)
{
mqd_t mqd;
char *ptr;
size_t len;
unsigned int prio;
if(argc != 4)
perror("./mqsend mqueue_name size prio!\n");
len = atoi(argv[2]);
prio = atoi(argv[3]);
mqd = mq_open(argv[1], O_WRONLY);
ptr = (char *)calloc(len, sizeof(char));
strcpy(ptr, "wjj_xyd");
mq_send(mqd, ptr, len, prio);
exit(0);
}
mqreceive.c
#include<stdio.h>
#include<stdlib.h>
#include<mqueue.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int main(int argc, char **argv)
{
int c, flags;
mqd_t mqd;
ssize_t n;
unsigned int prio;
char *buff;
struct mq_attr attr;
flags = O_RDONLY;
while((c = getopt(argc,argv, "n")) != -1)
{
switch(c){
case 'n':flags |= O_NONBLOCK;
break;
}
}
if(optind != argc - 1)
perror("mqreceive error!\n");
mqd = mq_open(argv[optind], flags);
mq_getattr(mqd, &attr);
buff = (char*)malloc(attr.mq_msgsize);
n = mq_receive(mqd, buff, attr.mq_msgsize, &prio);
printf("buff = %s, read %ld bytes, priority = %u\n",buff, (long)n, prio);
exit(0);
}
异步通知事件:
#include <stdio.h>#include <stdlib.h>#include <mqueue.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <signal.h>mqd_t mqd;struct mq_attr attr;struct sigevent sigev;char *ptr;unsigned int prio;size_t n;int rc;void sig_usr1(int signo);/*读取某消息队列,消息队列名通过参数传递*//*当有消息放置到某个空的队列中时产生SIGUSR1信号*/int main(int argc, char *argv[]){ if(argc != 2) { printf("Usage: mqnotifysig1 <name>\n"); exit(1); } /*只读模式打开消息队列*/ mqd = mq_open(argv[1], O_RDONLY); if(mqd < 0) { perror("打开消息队列失败"); exit(1); } // 取得消息队列属性,根据mq_msgsize动态申请内存 rc = mq_getattr(mqd, &attr); if(rc < 0) { perror("取得消息队列属性失败"); exit(1); } /*动态申请保证能存放单条消息的内存*/ ptr = calloc(attr.mq_msgsize, sizeof(char)); if(NULL == ptr) { printf("动态申请内存失败\n"); mq_close(mqd); exit(1); } //注册信号函数 signal(SIGUSR1, sig_usr1); sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGUSR1; //注册通知 rc = mq_notify(mqd, &sigev); // 读取前需要再次注册 if(rc < 0) { perror("通知注册失败"); mq_close(mqd); free(ptr); exit(1); } for(;;) { pause(); } return 0;}void sig_usr1(int signo){ rc = mq_notify(mqd, &sigev); // 读取前需要再次注册 if(rc < 0) { perror("通知注册失败"); mq_close(mqd); free(ptr); exit(1); } /*接收一条消息*/ n = mq_receive(mqd, ptr, attr.mq_msgsize, &prio); if(n < 0) { perror("读取失败"); mq_close(mqd); free(ptr); exit(1); } printf("读取 %ld 字节\n优先级为 %u\n", (long)n, prio);}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 消息队列
注意 在涉及到posix消息的函数时, gcc 编译时要加-lrt参数, 如 gcc -lrt unpipc.c mqpack.c send.c -o send gcc -lrt unpipc.c m ...
- 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 ...
随机推荐
- BZOJ1652 [Usaco2006 Feb]Treats for the Cows
蒟蒻许久没做题了,然后连动规方程都写不出了. 参照iwtwiioi大神,这样表示区间貌似更方便. 令f[i, j]表示i到j还没卖出去,则 f[i, j] = max(f[i + 1, j] + v[ ...
- grafana+influxdb安装
登录http://192.168.1.114:3000/login 2.修改完密码之后,进入主界面
- 第三视角团队:项目UML设计(团队)
项目UML设计(团队) 团队信息 团队名:第三视角 各成员学号及姓名 姓名 学号 博客链接 张扬(组长) 031602345 http://www.cnblogs.com/sxZhangYang/p/ ...
- 关于python课程的想法和建议。
第一次听说python是在刚结束与世隔绝的高中生活之后,当时的网络上铺天遍地都是人工智能和机器学习,于是便知道了python这门编程语言.我是光电信息科学与工程专业的学生,这个专业的学生必须要懂计算机 ...
- Nexus设备渗透测试平台 – Kali Linux NetHunter
NetHunter是一个基于Kali Linux为Nexus设备构建的Android渗透测试平台,其中包括一些特殊和独特的功能.NetHunter支持无线802.11注入,一键MANA AP搭建,HI ...
- WTForms组件
WTForms组件 WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证. 注意: from wtforms import Form 和 from flask_wtf ...
- Linux C 中获取local日期和时间 time()&localtime()函数
1. time() 函数 /* time - 获取计算机系统当前的日历时间(Calender Time) * 处理日期时间的函数都是以本函数的返回值为基础进行运算 * * 函数原型: * #incl ...
- 第三篇 makefile的伪目标
我们来思考一下makefile中的目标究竟是什么?实际上,在默认情况下: 1.make将makefile的目标认为是一个文件: 2.make解释器比较目标文件和依赖文件的新旧关系,决定是否 ...
- iOS7,iOS8和iOS9的区别
iOS7,iOS8和iOS9的区别:iOS7.0 1.iOS 7是iOS面世以来在用户界面上做出改变最大的一个操作系统.iOS 7抛弃了以往的拟物化设计,而采用了扁平化设计. 苹果在重新思考 iOS ...
- 20145209 2016-2017-2 《Java程序设计》第8周学习总结
20145209 2016-2017-2 <Java程序设计>第8周学习总结 教材学习内容总结 1.java.util.logging包提供了日志功能相关类与接口. 2.使用日志的起点是L ...