概念: 进程彼此之间可以通过IPC消息进行通信。进程产生的每条消息都被发送到一个IPC消息队列中,这条消息一直存放在队列中,直到另一个进程将其读走为止。

优点:可以通过发送消息来几乎完全避免命名管道的同步和阻塞问题;消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。而且,每个数据块被认为含有一个类型,接收进程可以独立地接收含有不同类型值的数据块。

缺点:每个数据块有一个最大长度的限制;系统中所有消息队列所包含的全部数据块的总长度也有一个上限。

基本原理: 消息是由固定大小的首部和可变长度的正文组成的;可以使用一个整数值标识消息,这就允许进程有选择的从消息队列中获取消息。只要进程从IPC消息队列中读出一条消息,内核就把这条消息删除;因此,一个进程只能接收一条给定的消息。当消息队列满时,则试图让新消息入队的进程可能被阻塞。当消息队列为空时,则接收进程甚至会被阻塞。

代码示例

发送信息的程序的源文件msgsend.c的源代码为:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h> #define MAX_TEXT 512
struct msg_st
{
long int msg_type;
char text[MAX_TEXT];
}; int main()
{
int running = ;
struct msg_st data;
char buffer[BUFSIZ];
int msgid = -; //建立消息队列
msgid = msgget((key_t), | IPC_CREAT);
if(msgid == -)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
} //向消息队列中写消息,直到写入end
while(running)
{
//输入数据
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
data.msg_type = ; //注意2, 用来设置发送的信息的信息类型,即其发送的信息的类型为1
strcpy(data.text, buffer);
//向队列发送数据
if(msgsnd(msgid, (void*)&data, MAX_TEXT, ) == -)
{
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}
//输入end结束输入
if(strncmp(buffer, "end", ) == )
running = ;
sleep();
}
exit(EXIT_SUCCESS);
}

接收信息的程序源文件为msgreceive.c的源代码为:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h> struct msg_st
{
long int msg_type;
char text[BUFSIZ];
}; int main()
{
int running = ;
int msgid = -;
struct msg_st data;
long int msgtype = ; //注意1,值为0表示获取队列中第一个可用的消息 //建立消息队列
msgid = msgget((key_t), | IPC_CREAT);
if(msgid == -)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
//从队列中获取消息,直到遇到end消息为止
while(running)
{
if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, ) == -)
{
fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s\n",data.text);
//遇到end结束
if(strncmp(data.text, "end", ) == )
running = ;
}
//删除消息队列
if(msgctl(msgid, IPC_RMID, ) == -)
{
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

如果把注意1,即msgreceive.c文件main函数中的语句由long int msgtype = 0;改变为long int msgtype = 2;会发生什么情况,msgreceive将不能接收到程序msgsend发送的信息。因为在调用msgrcv函数时,如果msgtype(第四个参数)大于零,则将只获取具有相同消息类型的第一个消息,修改后获取的消息类型为2,而msgsend发送的消息类型为1,所以不能被msgreceive程序接收。
msgreceive如果没有接收到信息和输出,而且当msgsend输入end结束后,msgreceive也不会结束,通过jobs命令我们可以看到它还在后台运行着。

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

  1. Linux进程间通信(二) - 消息队列

    消息队列 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据. 消息队列和之前讨论过的管道和FIFO有很大的区别,主要有以下两点(管道请查阅我的另一篇文章 ...

  2. 深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议

    前言 消息队列在现今数据量超大,并发量超高的系统中是十分常用的.本文将会对现时最常用到的几款消息队列框架 ActiveMQ.RabbitMQ.Kafka 进行分析对比.详细介绍 RabbitMQ 在 ...

  3. [转]Linux进程间通信——使用消息队列

    点击此处阅读原文 另收藏作者ljianhui的专栏初学Linux 下面来说说如何使用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linu ...

  4. 练习--LINUX进程间通信之消息队列MSG

    https://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 继续坚持,或许不能深刻理解,但至少要保证有印象. ~~~~~~~~~~~~~~ 消息队 ...

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

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

  6. Linux进程间通信(消息队列/信号量+共享内存)

    写在前面 不得不说,Deadline果真是第一生产力.不过做出来的东西真的是不堪入目,于是又花了一早上重写代码. 实验内容 进程通信的邮箱方式由操作系统提供形如 send()和 receive()的系 ...

  7. Linux进程间通信之消息队列

    本文依据以下思路展开,首先从宏观上阐述消息队列的机制,然后以具体代码为例进一步阐述该机制,最后试着畅想一下该通信机制潜在的应用. 消息队列是在两个不相关进程间传递数据的一种简单.高效方式,她独立于发送 ...

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

    消息队列就是一个消息的链表. 能够把消息看作一个记录,具有特定的格式以及特定的优先级.对消息队列有写权限的进程能够向中依照一定的规则加入新消息.有读权限的进程则能够读走消息. 读走就没有了.消息队列是 ...

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

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

随机推荐

  1. LOJ 103子串查找——用hash代替kmp算法

    题意 给出两个字符串 $s_1,s_2$,求 $s_2$ 在 $s_1$ 中出现的次数. 分析 预处理出两个字符串的哈希值,再逐位比较. 时间复杂度为 $O(n+m)$,和 $kmp$ 算法一样. 可 ...

  2. 读取Excel数据到DataTable

    读取Excel数据到DataTable 代码 /// <summary> /// 获取指定路径.指定工作簿名称的Excel数据:取第一个sheet的数据 /// </summary& ...

  3. pyharm 上运行 npm 配置方法

    问题解决.

  4. log4j2配置文件log4j2.xml详解

    配置全解 1.缺省默认配置文件 <?xml version="1.0" encoding="UTF-8"?> <Configuration s ...

  5. HEML与Css的基本理解

    什么是 HTML? HTML 就像造房子一样,一栋房子有多个组成部分,html类似于房子的户型,它设计了房子的整体架构.分区.布局,而且还定义了每个区块的功能作用.html技术为后续入住的数据事先搭建 ...

  6. MongoDB 建立与删除索引

    1.1 在独立服务器上面建立索引 在独立服务器上面创建索引,可以在空闲时间于后台建立索引. 在后台建立索引,可利用background:true参数运行 >db.foo.ensureIndex( ...

  7. fdisk分区命令

    fdisk是Linux系统中最常用的分区工具,通过这个命令也可以查看系统中所有可用的分区,但是这个命令只支持MBR的分区表(这句话应该只对某些系统,CentOS7-1810适用,Debian9.5和o ...

  8. leetcode解题报告(14):Max Consecutive Ones

    描述 Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: ...

  9. Python中一些高效的数据操作

    列表统计 chars = ["a", "b", "a", "c", "a", "d&quo ...

  10. synchronized的原理与使用

    理论层面: 内置锁与互斥锁 修饰普通方法.修饰静态方法.修饰代码块 demo如下: package com.roocon.thread.t3; public class Sequence { priv ...