linux进程间通信之Posix消息队列

Posix消息队列与System V 消息队列的用法很相似,主要有以下区别:
1. 对Posix消息队列的读取总是返回最高优先级的最早消息,对System V 消息队列的读取可以返回指定优先级的消息。
2. Posix 消息队列允许产生一个信号或启动一个线程去向一个空队列写入一个消息,System V消息队列不可以。

Posix消息队列常用函数及头文件
#include <mqueue.h>
1.  mqd_t mq_open(const char *name,int oflag,.../* mode_t mode, struct mq_attr *attr  */);
                                 返回值: 若成功则返回消息队列描述符,若出错返回-1

name:  为路径
oflag:    为O_RDONLY , o_WRONLY或O_RDWR之一,也可按位或上O_CREAT,O_EXCL,O_NONBLOCK.
当用O_CREAT表示去创建一个新消息队列且新消息队列不存在时,参数mode 和 attr 就需要了。
mode: 所属的用户权限
attr:用于给新队列指定某些属性,如果为空指针,即为默认属性。
mq_open 的返回值用于其他Posix消息队列函数的第一个参数

2.  int mq_close(mqd_t mqdes);
                        返回值:成功返回0,出错返回-1
     此函数功能是关闭该进程的该描述符指向的消息对列,但并不从系统中删除。

3. int mq_unlink(const char *name);
                        返回值:成功返回0,出错返回-1
     此函数功能是删除系统中name指向的消息对列。

4.  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);
                    返回值:成功返回0,出错返回-1
mq_attr结构有以下属性:
struct mq_attr{
    long mq_flags:        //消息队列标志: 0,O_NONBLOCK
    long mq_maxmsg;  //消息队列中允许的最多消息条数
    long mq_msgsize;    //每条消息中的最大字节数
    long mq_curmsgs;   //消息队列中当前的消息数
};

mq_attr结构的指针可以作为mq_open的第四个参数传递(mq_attr *attr), 从而使当创建新的Posix消息队列时可以指定mq_maxmsg和mq_msgsize属性,其他两个成语属性被mq_open忽略。

mq_getattr: 获取消息队列当前属性并填入attr指向的结构。
mq_setattr: 设置指定消息队列的属性,但是只使用mq_flags成员,以设置或清除费阻塞标志。其他三个成员属性被忽略(mq_maxmsg和mq_msgsize只能创建时指定,mq_curmsgs只能获取不能设                            置)。

5.   int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio);             返回值:成功返回0,出错返回-1

ssize_t mq_recieve(mqd_t mqdes, char *ptr, size_t len, unsigned int *priop);
             返回值:成功则返回消息中字节数,出错返回-1

mq_receive中的len参数的值不能小于mq_attr结构的mq_msgsize,否则,mq_receive立即返回EMSGSIZE错误。
mq_send中的prio参数是写入消息的优先级,必须小于MQ_PRIO_MAX。 如果mq_receive的priop是一个非空指针,则会存放返回消息的优先级。如果不使用优先级,可以mq_send时指定优先级为0,                          mq_receive时指定最后一个参数为空指针。

代码举例:

创建Posix消息对列mq_creat.c

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "mqueue.h"
  4. int main(char argc,char **argv)
  5. {
  6. mqd_t mqdc;
  7. if(argc>1)
  8. {
  9. mqdc=mq_open(argv[1],O_CREAT|O_RDWR|O_WRONLY,0666,NULL);
  10. if(mqdc==-1)
  11. printf("open error\n");
  12. mq_close(mqdc);
  13. }
  14. return 0;
  15. }

复制代码

Posix消息对列发送代码mq_send.c

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "mqueue.h"
  4. int main(char argc,char **argv)
  5. {
  6. mqd_t mqds;
  7. void *ptr;
  8. size_t len;
  9. unsigned int prio;
  10. if(argc<3)
  11. printf("usage: ./send <name> <#bytes> <priority>\n");
  12. else
  13. {
  14. len=atoi(argv[2]);
  15. prio=atoi(argv[3]);
  16. mqds=mq_open(argv[1],O_WRONLY);
  17. if(mqds==-1)
  18. printf("open error\n");
  19. ptr=calloc(len,sizeof(char));
  20. mq_send(mqds,ptr,len,prio);
  21. mq_close(mqds);
  22. }
  23. return 0;
  24. }

复制代码

Posix消息队列接收代码mq_receive.c

  1. #include "stdlib.h"
  2. #include "stdio.h"
  3. #include "mqueue.h"
  4. int main(char argc,char **argv)
  5. {
  6. mqd_t mqdr;
  7. ssize_t n;
  8. unsigned int prio;
  9. void *buff;
  10. struct mq_attr attr;
  11. if(argc>1)
  12. {
  13. mqdr=mq_open(argv[1],O_RDONLY);
  14. if(mqdr==-1)
  15. printf("open error\n");
  16. mq_getattr(mqdr,&attr);
  17. buff = malloc(attr.mq_msgsize);
  18. while((n=mq_receive(mqdr,buff,attr.mq_msgsize,&prio))<=0)
  19. {
  20. printf("wait\n");
  21. sleep(1);
  22. }
  23. printf("buff is %s,n=%d,prio=%d\n",buff,n,prio);
  24. mq_close(mqdr);
  25. }
  26. return 0;
  27. }

复制代码

运行结果:

首先运行creat 创建新的消息队列:    $ ./creat /mq_test

然后运行send 发送消息:
$ ./send /mq_test 20 2
$ ./send /mq_test 80 8
$ ./send /mq_test 40 4
$ ./send /mq_test 60 6

最后运行receive接收消息:
$ ./receive /mq_test
buff is ,n=80,prio=8
$ ./receive /mq_test
buff is ,n=60,prio=6
$ ./receive /mq_test
buff is ,n=40,prio=4
$ ./receive /mq_test
buff is ,n=20,prio=2

从运行结果来看,发送消息程序依次发送了优先级为2,8,4,6长度为20,80,40,60四个消息; 然后运行接收程序后首先接收到的是优先级最高为8,长度为80的消息,按优先级由高到低依次接收。
因为发送的数据是calloc出来的随机数据,打印结果无法显示,只能显示“buff is ”.

6.    int mq_notify(mqd_t mqdes, const struct sigevent *notification);
              返回值: 成功返回0,出错返回-1

此函数为指定Posix消息队列建立或删除异步事件通知。

注意点:
1)任意时刻只能一个进程注册接收某个消息队列通知。
2)通知接收到后,已存在的注册即被撤销,如果需要再次接收,需要再次注册。
3) 进程mq_receive的阻塞优先级大于注册接收通知的优先级。

原文地址:https://www.cnblogs.com/wudymand/p/9226463.html

时间: 2024-10-09 11:07:24

linux进程间通信之Posix消息队列的相关文章

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

Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字

Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间的通信方面的侧重点有所不同.前者是对UNIX早期的进程间通信手段进行了系统的改进和扩充,形成了“system V IPC”,其通信进程主要局限在单个计算机内:后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制.而Linux则把两者的优势都继承了下来 linux进程间通信(IPC)有几种方式

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

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

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进程通信之POSIX消息队列

进程间的消息队列可以用这个实现,学习了下. http://blog.csdn.net/anonymalias/article/details/9799645?utm_source=tuicool&utm_medium=referral 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点: 一个进程向消息队列写入消息之前,并不需要某个进程在该队列上等待该消息的到达,而管道和FIFO是相

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

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

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

细说linux IPC(九):posix消息队列

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 消息队列可以看作一系列消息组织成的链表,一个程序可以往这个链表添加消息,另外的程序可以从这个消息链表读走消息. mq_open()函数打开或创建一个posix消息队列. #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode cons

进程间通信(IPC)之消息队列

★IPC方法包括管道(PIPE).消息队列(Message_Queue).旗语.共用内存(ShareMemory)以及套接字(Socket).进 程间通信主要包括了管道.系统IPC(包括了消息队列.信号以及共享存储).套接字(SOCKET).此文将详细叙述消息队列的相 关内容. ★产生原因: 所谓消息队列,其实就是消息(数据)传输过程中保存的容器.既然有了管道通信的方式,何必又有消息队列呢? 因为根据管道的特性,我们知道其在一定程度上存在或多或少的局限性,首先匿名管道以及命名管道是随进程的,进