linux网络编程之posix消息队列

在前面已经学习了System v相关的IPC,今天起学习posix相关的IPC,关于这两者的内容区别,简单回顾一下:

《linux网络编程之posix消息队列》

而今天先学习posix的消息队列,下面开始:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

 接下来则编写程序来创建一个posix消息队列:

《linux网络编程之posix消息队列》

下面来编译运行一下:

《linux网络编程之posix消息队列》

这是为什么呢?其实在man帮助中有说明:

《linux网络编程之posix消息队列》

所以,修改一下Makefile文件,加上这个链接选项:

《linux网络编程之posix消息队列》

再来运行一下:

《linux网络编程之posix消息队列》

posix消息队列创建成功了,下面来查看一下:

《linux网络编程之posix消息队列》

这是为什么呢?原因是由于ipcs只能查看System v创建的消息队列,而poix创建的消息队列不能通过这个方式来查看,那到底存放在哪里呢?还是回到强大的man帮助手册来找寻答案:

《linux网络编程之posix消息队列》

所以接下来创建一个挂载点:

《linux网络编程之posix消息队列》

接下来将消息队列虚拟文件系统挂载到该目录下:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

所以来看一下目前我们所创建的消息队列的状态:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

如果要想再次看到,则需重新挂载一次既可。

在创建posix消息队列时,我们指定了一个消息队列名字,如下:

《linux网络编程之posix消息队列》

其中该名字是有一定的规则的,所以接下来说明一下

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

接下来要学习的一个函数比较简单,关闭消息队列:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

【说明】:它的更准备的含义是删除一个连接数,直接连接数减为0的时候才真正将文件删除。

《linux网络编程之posix消息队列》

下面来编写程序来使用一下:

《linux网络编程之posix消息队列》

编译运行:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

其中stuct mq_attr结构体为:

《linux网络编程之posix消息队列》

下面来编译程序来获取一下消息队列的属性:

《linux网络编程之posix消息队列》

编译运行:

《linux网络编程之posix消息队列》

另上设置属性的用法类似,这里就不编写了。

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

接下来利用这个函数来向消息队列中发送消息:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

下面来编译运行:

《linux网络编程之posix消息队列》

另外也可以用我们自己编写的查看属性的程序来查看此时的属性:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

现在创建的消息队列中已经发送了一个消息了,接下来将从消息队列中来获取已发送的消息:

《linux网络编程之posix消息队列》

下面编译运行:

《linux网络编程之posix消息队列》

这是为什么呢?

《linux网络编程之posix消息队列》

而最大长度大小可以通过mq_attr函数来获取,所以修改一个代码:

《linux网络编程之posix消息队列》

下面再次编译运行:

《linux网络编程之posix消息队列》

下面重新再来发送多个消息,再接收:

《linux网络编程之posix消息队列》

没有消息了,接收则会被阻塞,从运行效果中可以看出。

《linux网络编程之posix消息队列》

从函数字面意思来看是一个通知,当消息队列从没消息到有消息会得到通知,这个是System V跟Posix消息队列的一个非常明显的区别,就是SystemV消息队列是没法得到这个通知的,而Posix消息队列是可以的,也就是目前消息队列是空的,当某个进程或线程往消息队列发送一条消息时,这时消息队列则会给出通知,只要进程注册了该通知事件,而注册通知就可以通过mq_notify函数完成,具体如下:

《linux网络编程之posix消息队列》

其中用到的结构体:

《linux网络编程之posix消息队列》

可以查看一下man帮助:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

这里主要关注信号的方式,因为线程目前还没有学到:

《linux网络编程之posix消息队列》

下面编写程序来演示一下通知的效果:

《linux网络编程之posix消息队列》

接下来注册一个消息队列的通知事件:

《linux网络编程之posix消息队列》

当收到通知时,这时来处理一下信号处理程序:

《linux网络编程之posix消息队列》

另外,为了看到通知效果,这里需要不让进程退出,所以死循环一下:

《linux网络编程之posix消息队列》

下面编译运行来看下效果:

《linux网络编程之posix消息队列》

从中发现,当空的消息队列里面新发送了一条消息,则立马就收到通知了,那如果继续再发送呢?

《linux网络编程之posix消息队列》

这是为什么呢?其实这个通知是有一定规则的,如下:

《linux网络编程之posix消息队列》

《linux网络编程之posix消息队列》

要想让每次发送都收到通知,则上面的第三点则是解决方案,下面来修改一下程序:

《linux网络编程之posix消息队列》

下面再来看下效果:

《linux网络编程之posix消息队列》

从中可以发现,这次确实是每次发送消息都能被通知到了,那规则中提到,重新注册必须放到接收消息之前,不能放在之后:

《linux网络编程之posix消息队列》

这是为什么呢?这时因为当发送一个消息时,被接收了之后,消息队列里面就为空了,这时再次注册就无法接收到通知了,所以得放在接收消息之前再次注册。

最后来说明一下在上面提到过需要解释的:

《linux网络编程之posix消息队列》

正好可以利用这个通知程序来说明,如下:

《linux网络编程之posix消息队列》

关于Posix的消息队列就学到这,下次继续~

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/webor2006/p/4225388.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注