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

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 }

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 }

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 }

时间: 2024-11-12 07:02:28

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

考试备战系列--软考--02基础知识复习

这部分主要是计算机基础知识的概念介绍,相关系列文章如下所示. 考试备战系列--软考--01基础架构概念 考试备战系列--软考--02基础知识复习 考试备战系列--软考--03综合知识复习 考试备战系列--软考--04考题收集 考试备战系列--软考--05案例收集 考试备战系列--软考--06论文准备 操作系统时计算机系统的核心系统软件,其他软件均建立在其上,其分类包括:单用户操作系统和批处理操作系统.分时操作系统和实时操作系统.网络操作系统和分布式操作系统.嵌入式操作系统.其4大特征为并发性.共

php高级进阶系列文章--第二篇(PHP基础知识复习)

php基础知识复习 本文中对于简单的知识点只会提及一下(例如什么控制结构什么的),对于较有难度的详细复习下(例如面向对象的反射等等) 再次申明,本系列文章不是从最基础的开始复习,对于零基础的可能不适用,本文的初衷是我要准备攻读源码,在攻读前将之前的知识牢固下,太过简单的就写在文中了 1,echo print echo 可以输出一个或者多个字符串 print 只可以输出一个字符串,返回值总为1 2,PHP7中的组合比较符 echo 1 <==> 1 // 0 echo 1 <==>

Linux 进程间通信(posix消息队列 简单)实例

Linux 进程间通信(posix消息队列 简单)实例 详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm 编译: gcc -o consumer consumer.c -lrt gcc -o producer producer.c -lrt /* * * Filename: producer.c * * Description: 生产者进程 * * Version: 1.0 * Created: 09/30/2011 04:52:23 PM

Posix消息队列相关函数

Posix消息队列(message queue) IPC函数中常用的参数取值: 打开或创建POSIX IPC对象所用的各种oflag常值o_RDONLY   只读O_WRONLY   只写O_RDWD     读写O_CREAT    若不存在则创建,存在则引用O_EXCL     排他性创建,需要和O_CREAT一起使用,当对象不存在时才创建,否则返回EEXIST错误O_NONBLOCK 非阻塞模式O_TRUNC    若已存在则截短 创建新的IPC对象所用的mode常值: S_IRUSR  

Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用

posix消息队列与system v消息队列的差别: (1)对posix消息队列的读总是返回最高优先级的最早消息,对system v消息队列的读则可以返回任意指定优先级的消息. (2)当往一个空队列放置一个消息时,posix消息队列允许产生一个信号或启动一个线程,system v消息队列则不提供类似机制. 队列中的每个消息具有如下属性: 1.一个无符号整数优先级(posix)或一个长整数类型(system v) 2.消息的数据部分长度(可以为0) 3.数据本身(如果长度大于0) Posix消息队

Linux IPC实践(7) --Posix消息队列

1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <mqueue.h> mqd_t mq_open(const char *name, int oflag); //专用于打开一个消息队列 mqd_t mq_open(const char *name, int oflag, mode_t mode

UNIX IPC: POSIX 消息队列

首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边.在Ubuntu上使用正常,不过POSIX消息队列通过ipcs命令是看不到的,需要通过如下方式进行查看: mount -t mqueue none /mnt ls -al /mnt ls列出的文件即为程序中创建的POSIX消息队列,消息队列的名称需要以“/”开头否则会提示参数非法.通过cat查看这个文件可以知道这个队列的一些参数如: [email

Linux环境编程之IPC进程间通信(五):Posix消息队列1

对于管道和FIFO来说,必须应该先有读取者存在,否则先有写入者是没有意义的.而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每个消息都是一个记录,它由发送者赋予一个优先级.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.消息队列是随内核的持续性,一个进程可以往某个队列写入一些消息,然后终止,再让另外一个进程在以后的某个时刻读出这些消息.这跟管道和FIFO不一样,当一个管道或FIFO的最后一次关闭时

进程间通信(二)——Posix消息队列

1.概述 消息队列可认为是消息链表.有足够写权限的线程可以往队列中放置消息,有足够读权限的进程可以从队列中取走消息.每个消息是一个记录,由发送着赋予一个优先级. 在像队列中写入消息时,不需要某个进程在该队列上等待消息到达.这与管道不同,管道必须现有读再有写. 消息队列具有随内核的持续性,与管道不同.进程结束后,消息队列中消息不会消失.当管道最后一次关闭,其中的数据将丢弃. 消息队列具有名字,可用于非亲缘关系的进程间. Posix消息队列读总是返回最高优先级的最早消息,而System V消息队列的