一、什么是消息队列
unix早期通信机制之一的信号能够传送的信息量有限,管道则只能传送无格式的字节流,这无疑会给应用程序开发带来不便。消息队列(也叫做报文队列)则克服了这些缺点。

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式。
进程可以向其中按照一定的规则添加新消息;另一些进程则可以从消息队列中读走消息。

消息队列分两种:
POSIX消息队列以及系统V消息队列 系统V消息队列目前被大量使用

Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度。

二、在Linux中使用消息队列
Linux提供了一系列消息队列的函数接口来让我们方便地使用它来实现进程间的通信。它的用法与其他两个System V PIC机制,即信号量和共享内存相似。

消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述符,必须提供该消息队列的键值。

#include <sys/types.h>
#include <sys/ipc.h>key_t ftok(char *pathname, char proj);

功能:返回文件名对应的键值。
pathname:文件名
proj:项目名(不为0即可)

1、msgget函数
该函数用来创建和访问一个消息队列。它的原型为:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgget(key_t, key, int msgflg);  

key: 键值,由ftok获得
msgflg:标志位
返回值:与键值key相对应的消息队列的描述符。

msgflg取值:
IPC_CREAT
创建新的消息队列
IPC_EXCL
与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误。
IPC_NOWAIT
读写消息队列要求无法得到满足时,不阻塞。

在以下两种情况下,将创建一个新的消息队列:
如果没有与键值key相对应的消息队列,并且msgflg中包含了IPC_CREAT标志位。
key参数为IPC_PRIVATE

2、msgsnd函数
该函数用来把消息添加到消息队列中。它的原型为:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgsnd(int msqid, struct msgbuf * msgp, int msgsz, int msgflg)

功能:向消息队列中发送一条消息
msqid:消息队列描述符
msgp:消息队列指针,指向存放消息的结构
msgsz:消息数据长度
msgflg:发送标志,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待
如果调用成功,消息数据的一分副本将被放到消息队列中,并返回0,失败时返回-1.

消息格式:

struct msgbuf
{long mtype;     // 消息类型 > 0char mtext[1];  // 消息数据的首地址
}

3、msgrcv函数
该函数用来从一个消息队列获取消息,它的原型为:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int msgrcv(int msqid, struct msgbuf* msgp, int msgsz, long msgtp, int msgflg)

功能:从msqid代表的消息队列中读取一个msgtyp类型的消息,并把消息存储在msgp指向的msgbuf结构中。在成功的读取了一条消息以后,队列中的这条消息将被删除。

msgtype可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。

调用成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1.

4、msgctl函数
该函数用来控制消息队列,它与共享内存的shmctl函数相似,它的原型为:

int msgctl(int msgid, int command, struct msgid_ds *buf);

command是将要采取的动作,它可以取3个值,
IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
IPC_RMID:删除消息队列

buf是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员:

struct msgid_ds
{  uid_t shm_perm.uid;  uid_t shm_perm.gid;  mode_t shm_perm.mode;
};  

成功时返回0,失败时返回-1.

三、使用消息队列进行进程间通信
马不停蹄,介绍完消息队列的定义和可使用的接口之后,我们来看看它是怎么让进程进行通信的。由于可以让不相关的进程进行行通信,所以我们在这里将会编写两个程序,msgreceive和msgsned来表示接收和发送信息。根据正常的情况,我们允许两个程序都可以创建消息,但只有接收者在接收完最后一个消息之后,它才把它删除。
发送:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>struct msgbuf
{long mtype;     /* message type, must be > 0 */char mtext[256];  /* message data */
};int main()
{// 创建消息队列int msgid = msgget((key_t)1234, 0666|IPC_CREAT);if (msgid == -1){perror ("msgget");return -1;}struct msgbuf  msg;msg.mtype = 2;strcpy (msg.mtext, "hello");int ret = msgsnd(msgid, &msg, 256, IPC_NOWAIT);if (ret == -1){perror ("nsgsnd");return -1;}return 0;
}

接收:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>struct msgbuf
{long mtype;     /* message type, must be > 0 */char mtext[256];  /* message data */
};int main()
{// 创建消息队列int msgid = msgget((key_t)1234, 0666|IPC_CREAT);if (msgid == -1){perror ("msgget");return -1;}struct msgbuf  msg;int ret = msgrcv(msgid, &msg, 256, 2, IPC_NOWAIT);if (ret == -1){perror ("msgrcv");return -1;}printf ("%s\n", msg.mtext);return 0;
}

进程间通信之消息队列相关推荐

  1. linux消息通信无法接收,进程间通信:消息队列有关问题:进程1接收不到进程2的消息...

    进程间通信:消息队列有关问题:进程1接收不到进程2的消息 进程间通信:消息队列有关问题:进程1接收不到进程2的消息 日期:2014-05-16 浏览次数:20365 次 进程间通信:消息队列问题:进程 ...

  2. linux 消息对lie_Linux进程间通信之消息队列总结

    一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符( i d ...

  3. c语言系统编程八:Linux进程间通信之消息队列

    Linux进程间通信之消息队列 一 消息队列概述 二 消息队列的特点 三 消息队列的创建和使用 3.1 获取系统唯一的key值 3.2 创建消息队列 3.3 查看消息队列和删除消息队列的shell命令 ...

  4. Linux进程间通信(IPC)-------消息队列

    消息队列是进程间通信的一种方法,他有两个操作,一个进程来发送消息(也就是向内存中写入数据),另一个是获取消息(也就是另外一个进程在内存中读取数据) 下面来看消息队列的 创建,写入,读取等需要用到的函数 ...

  5. 【Linux系统编程】进程间通信之消息队列

    00. 目录 文章目录 00. 目录 01. 消息队列概述 02. 消息队列相关函数 03. 消息队列读写操作 04. 测试代码 05. 附录 01. 消息队列概述 消息队列提供了一种在两个不相关的进 ...

  6. 进程间通信:消息队列概念及代码

    前言 接下讨论的IPC机制,它们最初由System V版本的Unix引入.由于这些机制都出现在同一个版本中并且有着相似的编程接口,所以它们被称为System V IPC机制.接下来的内容包括: 信号量 ...

  7. Linux进程间通信——使用消息队列

    下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信--使用命名管道 一.什么是消息队列 消息队列提供了 ...

  8. 进程间通信之---消息队列

    目录 消息队列 1.消息队列的原理 2.消息队列的接口: 2.1创建消息队列 2.2向消息队列发送消息 2.3接收消息: 2.4操作消息队列的接口 2.5代码测试: 信号量: 信号量的原理 消息队列 ...

  9. linux用函数输出进程信息,进程间通信之-消息队列(Message)--linux内核剖析(十一)...

    消息队列 消息队列 (也叫做报文队列)是Unix系统V版本中3种进程间通信机制之一.另外两种是信号量和共享内存. 这些IPC机制使用共同的授权方法.只有通过系统调用将标志符传递给核心之后,进程才能存取 ...

最新文章

  1. R语言 非中心化F分布
  2. pandas 数据索引与选取
  3. vue.js中mock本地json数据
  4. java内部类为什么使用很少_java内部类有什么好处?为什么需要内部类?
  5. java继承原理内存角度_Java编程的逻辑 (17) - 继承实现的基本原理
  6. Maven学习总结(58)—— 常用的 Maven 镜像地址和中央仓库地址汇总
  7. 极酷WIFI深度剖析免费WIFI
  8. 拓端tecdat|matlab预测ARMA-GARCH 条件均值和方差模型
  9. 不考虑知识点,考代码段更好
  10. 嵌入式系统笔记之声音
  11. 判断中心对称图形C语言
  12. Persistent.
  13. 文兵生日--2010-12-1
  14. Tomcat部署多个Sring Boot项目时Unable To Register MBean Exception的一种解决方法
  15. CNN中的小tips
  16. ptb同一屏呈现两张图片matlab,PTB-3 安装手册
  17. 平板电脑性价比排行2022
  18. python爬虫需要哪些基础知识-【PYTHON】【爬虫】关于python爬虫的一些基础知识
  19. 解决word插入的图片不能正常显示
  20. 在局域网中搭建自己的网站

热门文章

  1. 摩托罗拉ex232java_摩托罗拉ex232r如何刷机?摩托罗拉ex232r评测
  2. linux禁止客户端上传文件_Linux下Shell脚本实现FTP自动上传和下载文件
  3. leetcode1103. 分糖果 II 该模拟就模拟,别老想着优化
  4. 面向对象思想精华总结
  5. python学习实例(1)
  6. C++(STL):23 ---序列式容器queue源码剖析
  7. Python面试题-交换两个数字的三种方法
  8. CSDN-Markdown编辑器使用小技巧
  9. python输入程序_python程序的输入输出(acm的几个小程序)
  10. STL源码剖析 set