Posix消息队列可以认为是一个消息链表. 有足够写权限的线程可以往队列中放置消息, 有足够读权限的线程可以从队列中取走消息

在某个进程往一个队列写入消息前, 并不需要另外某个进程在该队列上等待消息的到达.

这跟管道和FIFO是相反的, 因为对于管道,FIFO来说, 除非读出者已经存在, 光有写入者是没有意义的。一个进程在往某消息队列写入消息后, 终止进程. 另一个进程某时刻读出该消息;然而对于管带或FIFO而言, 当管道或FIFO的最后一次关闭发生时,仍在管道或FIFO中的数据将被抛弃

消息队列的布局如下图

下面介绍队列用到函数:

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

函数打开或者创建一个posix消息队列。当我们的实际操作是创建一个新的队列时(即所要创建的队列不存在, 且oflag中已经指定O_CREAT), mode 和 attr参数是需要的.
函数的返回值称为消息队列描述符, 这个值用作其他消息队列操作函数的第一个参数值。另外根据man 7 mq_overview里面的介绍。在链接的时候必须链接librt库,采用-lrt的方法

如果没有链接的话,会出现下面的错误

root@zhf-maple:/home/zhf/codeblocks_prj/unix_network# gcc -c main.c -o main_tmp

root@zhf-maple:/home/zhf/codeblocks_prj/unix_network# ./main_tmp test2

bash: ./main_tmp: 无法执行二进制文件: 可执行文件格式错误

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:结构体如下:

struct mq_attr {

long mq_flags;       /* Flags: 0 or O_NONBLOCK */

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

————在mq_setattr中设置;

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

long mq_maxmsg;      /* Max. # of messages on queue */

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

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

long mq_msgsize;     /* Max. message size (bytes) */

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

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

long mq_curmsgs;     /* # of messages currently in queue */

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

————在mq_getattr中获得。

};

2 int mq_close(mqd_t mqdes):关闭消息队列

关闭之后调用进程不在使用该描述符,但消息队列不会从系统中删除,进程终止时,会自动关闭已打开的消息队列,和调用mq_close一样。参数为mq_open()函数返回的值

3  int mq_unlink(const char *name): 从系统中删除某个消息队列

删除会马上发生,即使该队列的描述符引用计数仍然大于0。参数为mq_open()函数第一个参数。

4设置和获取队列属性

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

int mq_setattr(mqd_t mqdes, struct mq_attr *newattr,  struct mq_attr *oldattr);

参数mqdes为mq_open()函数返回的消息队列描述符。

参数attr、newattr、oldattr为消息队列属性结构体指针;

5向消息队列放置和取走消息

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

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

参数msg_ptr为指向消息的指针。

msg_len为消息长度,该值不能大于属性值中mq_msgsize的值。

msg_prio为优先级,消息在队列中将按照优先级大小顺序来排列消息。

如果消息队列已满,mq_send()函数将阻塞,直到队列有可用空间再次允许放置消息或该调用被信号打断;如果O_NONBLOCK被指定,mq_send()那么将不会阻塞,而是返回EAGAIN错误。如果队列空,mq_receive()函数将阻塞,直到消息队列中有新的消息;如果O_NONBLOCK被指定,mq_receive()那么将不会阻塞,而是返回EAGAIN错误。

下面就来看第一个例子:

#include <stdlib.h>

#include <sys/stat.h>

#include <unistd.h>

#include <sys/types.h>

#include <mqueue.h>

#include <fcntl.h>

#include "func.h"

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

int main(int argc,char **argv)

{

int     c,flags;

mqd_t   mqd;

struct mq_attr  attr;

flags = O_RDWR|O_CREAT;

printf("create mqueue.\n");

if((mqd = mq_open(argv[1],flags,FILE_MODE,NULL)) == -1)

{

perror("mq_open() error");

exit(-1);

}

mq_getattr(mqd,&attr);

printf("max #msgs = %ld,max #bytes/msg = %ld,#currently on queue = %ld\n",attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);

mq_close(mqd);

exit(0);

}

在执行代码前,首先要创建消息队列存放的路径。一般是/dev/mqueue。没有的话需要创建一个。然后执行mount -t mqueue none /dev/mqueue进行挂载。参考说明如下

gcc main.c -o main_tmp -lrt

./main_tmp /test123

执行完后,在dev/mqueue路径下面就能看到创建的队列文件以及队列里面的信息。

cat /dev/mqueue/test123

QSIZE:0          NOTIFY:0     SIGNO:0     NOTIFY_PID:0

linux c编程:Posix消息队列的更多相关文章

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

    Linux 进程间通信(posix消息队列 简单)实例 详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm 编译: gcc -o consumer ...

  2. POSIX 消息队列 和 系列函数

    一.在前面介绍了system v 消息队列的相关知识,现在来稍微看看posix 消息队列. posix消息队列的一个可能实现如下图: 其实消息队列就是一个可以让进程间交换数据的场所,而两个标准的消息队 ...

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

    posix消息队列与system v消息队列的区别: (1)对posix消息队列的读总是返回最高优先级的最早消息,对system v消息队列的读则能够返回随意指定优先级的消息. (2)当往一个空队列放 ...

  4. [转]Linux进程通信之POSIX消息队列

    进程间的消息队列可以用这个实现,学习了下. http://blog.csdn.net/anonymalias/article/details/9799645?utm_source=tuicool&am ...

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

    1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...

  6. Linux IPC POSIX 消息队列

    模型: #include<mqueue.h> #include <sys/stat.h> #include <fcntl.h> mq_open() //创建/获取消 ...

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

    对于管道和FIFO来说.必须应该先有读取者存在.否则先有写入者是没有意义的. 而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每一个 ...

  8. linux网络编程之posix消息队列

    在前面已经学习了System v相关的IPC,今天起学习posix相关的IPC,关于这两者的内容区别,简单回顾一下: 而今天先学习posix的消息队列,下面开始: 接下来则编写程序来创建一个posix ...

  9. 进程间通信--POSIX消息队列

    相关函数: mqd_t mq_open(const char *name, int oflag); mqd_t mq_send(mqd_t mqdes, const char *msg_ptr, si ...

随机推荐

  1. How to check the 'OLE DB Destination' INPUT and OUTPUT

    Step 1: Step 2: Step 3:

  2. Linux非阻塞IO(四)非阻塞IO中connect的实现

    我们为客户端的编写再做一些工作. 这次我们使用非阻塞IO实现connect函数. int connect(int sockfd, const struct sockaddr *addr, sockle ...

  3. chown将指定文件的拥有者改为指定的用户或组(转)

    chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID:组可以是组名或者组ID:文件是以空格分开的要改变权限的文件列表,支持通配符.系统管理员经常使用chown命令,在将文件拷贝 ...

  4. VM里面的桥接

      今天我们谈一谈桥接模式,一般的时候,我用的是NAT模式,需要设置另一个虚拟网卡的IP地址,而不是借助本机的物理网卡.   编辑---虚拟网络编辑器 有些时候直接设置桥接到某个网卡可能会不成功,我们 ...

  5. jetty学习小结

    1.什么是jetty? 开源HTTP服务器和Servlet引擎,是web应用的容器,同tomcat类似.由于其轻量灵活的特性,很多知名产品也应用了它,如maven.eclipse.hadoop.spa ...

  6. mongodb在Windows安装配置及遇到的问题、java连接测试

    一.安装 1.访问mongodb的官网http://www.mongodb.org/downloads下载64bit的包,我下载的是mongodb-win32-x86_64-2008plus-ssl- ...

  7. 操作log.py

    # 把双数日期的日志,里面给随便写点东西# 1.获取到log目录下的所有文件os.walk()# 2.根据文件名来判断,是否是双数日期,分割字符串,取到日期# 3.12%2==0# 4.打开这个文件 ...

  8. 阿里CI/CD、DevOps、分层自动化技术

    原文地址:http://www.infoq.com/cn/news/2017/01/alibaba-yunxiao-cicd-devops 在互联网时代,产品快速迭代的重要性不言而喻.不管是传统企业还 ...

  9. 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效

    数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...

  10. linux之ftp命令详解

    我们在使用ftp客户端访问到ftp服务器之后,往往需要进行相关操作,比如从远程机器上下载文件,或者将文件传输到远程机器上.需要使用ftp的相关命令,本文讲述了ftp常用的一些操作. 方法/步骤     ...