Linux 进程间通信——消息队列

一、消息队列的原理

消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。每个数据块都被认为含有一个类型,接收进程可以独立接收含有不同类型值得数据库。

在这里插入图片描述
消息实际上是一个数据块,这个数据块是一个结构体,结构体由自己命名。消息的第一个成员是固定的,它是一个长整型,它代表消息的类型,后面的成员是自己定义的数据。一开始消息队列是空的,可以由一个进程a向消息队列中发送消息,但是如果由另外一个进程b或c去接收消息队列中的消息就会发生阻塞。当一个进程往消息队列中发送消息时,只要这个消息队列没有满,就可以添加进去,如果消息队列满了,就会发生阻塞。当一个进程去接收消息队列中的消息时可以指定消息的类型,当消息队列中没有所指定的消息的类型,进程就会发生阻塞。

1.消息队列与有名管道

消息队列和有名管道有许多相似之处

相同点:

使用消息队列并没有解决我们在使用有名管道时遇到的一些问题,比如管道满时的阻塞问题,在消息队列中同样存在,消息队列满时也会发生阻塞。

不同点:

消息队列相比较管道来说,消息队列少了在打开和关闭管道方面的复杂性。消息队列提供了一种在两个不相关的进程之间传递数据的相当简单且有效的方法。与有名管道相比,消息队列独立于发送和接收进程而存在,这消除了在同步有名管道的打开和关闭时会产生的一些困难。

2.消息队列得优缺点:

(1)优点:

①可以通过发送消息来几乎完全避免有名管道得同步和阻塞问题。

②可以用一些方法来提前查看紧急消息。

缺点:

与管道一样,每个数据块都有一个最大长度得限制,系统中所有队列所包含得全部数据块得总长度也有一个上限。Linux系统有两个宏定义MSGMAX和MSGMNB,它们以字节为单位分别定义了一条消息的最大长度和一个队列的最大长度。其它系统中这些宏定义可能会不一样或者不存在。

3.消息队列的生命周期

消息队列的生命周期并不随进程的结束而结束,是随内核持续的。调用消息队列相关的内核的接口,内核帮忙创建,只要自己不主动去删除,就会一直存在,即便进程已经结束,它们也一直会在内核中被维护着。想用的时候还可以继续用,在程序最后不使用的情况下把它删除。删除的方法有3种,关机、调用相关函数删除和在命令行手动删除。

信号量、共享内存的生命周期也是如此。

二、消息队列相关接口函数

1.msgget() 创建消息队列

创建或者获取一个消息队列的ID

 int msgget(key_t key, int msqflg);   

参数解释:
key:“房间密码”
msqflg:创建消息队列的方式,同时设置权限
返回值:成功返回消息队列id,失败返回 -1

权限的设置规则:

IPC_CREAT:可以单独使用,如果消息队列不存在,则重新开辟,函数返回值是新开辟的消息队列的ID;如果已经存在,则沿用已有的消息队列,函数返回值是已有的消息队列的ID。

IPC_EXCL:无法单独使用,要配合IPC_CREAT使用,即 IPC_CREAT | IPC_EXCL,表示如果消息队列不存在,则重新开辟,函数返回值是新开辟的消息队列ID;如果已经存在,则报错。

IPC_CREAT | IPC_EXCL | 0664:开辟消息队列的同时,设置消息队列的访问权限

2.msgsnd() 向消息队列中添加一条消息

该函数的作用是向消息队列中添加一条消息。

int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);

参数解释:

msgid:消息队列ID,即msgget函数的返回值
msgp: 消息缓冲区的地址,也就是你要向消息队列中添加的消息,需要满足一定的格式。消息格式如下:

  struct msgbuf  
{  
	long  mtype;   // 消息类型, 必须大于0  
	char  mtext[1]; //  消息数据  
	//(结构体的最后一个成员是数组,该数组也被称为柔性数组,即数组大小可变)
};  

msgsz:指定mtext中有效数据的长度。这里的消息长度指的是上面这个结构体中buf成员所占字节数。
msgflag:表示发送消息的方式。一般设置为0。也可以设置IPC_NOWAIT。可选值及其含义如下:

在这里插入图片描述
返回值:成功返回0,失败返回-1

3.msgrcv())接收一条消息

该函数的作用是从消息队列的队头取出一条消息。

ssize_t msgrcv(int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg);   

参数解释:

msgid:消息队列id
msgp:输出型参数,表示消息缓冲区的地址。也就是你要把取出来的消息放在哪,同样需要使用指定格式。数据格式和msgsnd函数所要添加的消息的格式一样,如下:

  struct msgbuf  
{  
	long  mtype;   // 消息类型, 必须大于0  
	char  mtext[1]; //  消息数据  
	//(结构体的最后一个成员是数组,该数组也被称为柔性数组,即数组大小可变)
};  

size:用于存放接收到的消息数据的缓冲区大小。
msgtype:选择想要取出的消息类型(虽然叫做消息队列,但是不一定就是取出队头元素,也可以是取出具有相同消息类型中的第一个消息)。主要分为以下三种情况:

在这里插入图片描述

msgtype < 0的具体解释:假设消息队列里的消息类型有 1、3、4、5 四种类型的消息,如果msgtype = -4,绝对值是4,那就需要取出消息类型小于等于4的所有消息,因此,取出消息的消息类型必须是1、3、4类型。

msgflag:表示接收消息的方式。一般设置为0,也可以设置IPC_NOWAIT等,可选值如下:

在这里插入图片描述
返回值: msgrcv()成功返回mtext中接收到的消息数据的长度, 失败返回-1。

4.msgctl()一般用来销毁消息队列

该函数的作用是控制消息队列,一般用来销毁消息队列。

int msgctl(int msqid, int cmd, struct msqid_ds *buf);  

参数解释:

msgid:消息队列id
cmd:对消息队列执行的具体操作,如拷贝、查询、销毁等。可选值如下:

在这里插入图片描述

buf:消息队列缓冲区。比如 cmd 为IPC_STAT时,会把消息队列的相关信息拷贝到该缓冲区中。
返回值:msgctl()成功返回0,失败返回-1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/82078.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

奇舞周刊第503期:图解串一串 webpack 的历史和核心功能

记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 图解串一串 webpack 的历史和核心功能 提到打包工具&#xff0c;可能你会首先想到 webpack。那没有 webpack 之前&#xff0c;都是怎么打包的呢&#xff1f;webpack 都有哪些功能&…

网络编程套接字(1)

文章目录 网络编程套接字(1)1. 预备知识1.1 源IP与目的IP1.2 认识端口号1.3 理解 "端口号" 和 "进程ID"1.4 源端口号和目的端口号1.5 认识TCP协议和UDP协议(1) TCP(2) UDP 1.6 网络字节序 2. socket编程接口2.1 socket 常见API2.2 sockaddr结构 网络编程套…

matplotlib绘制位置-时序甘特图

文章目录 1 前言2 知识点2.1 matplotlib.pyplot.barh2.2 matplotlib.legend的handles参数 3 代码实现4 绘制效果5 总结参考 1 前言 这篇文章的目的是&#xff0c;总结记录一次使用matplotlib绘制时序甘特图的经历。之所以要绘制这个时序甘特图&#xff0c;是因为22年数模研赛C…

【⑫MySQL | 约束(二)】外键 | 默认值 | 检查约束 — 综合案例

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL外键 | 默认值 | 检查约束 以及综合案例的分享✨ 目录 前言6. 外键约束(FOREIGN KEY,FK)7. 默认值约束和检查约束8. 综合实战总结 6. 外键约束(FOREIGN KEY,FK) 前面介绍的完整性约束都是在单表中进行设置&…

JavaScript 快速入门手册

本篇文章学习&#xff1a; 菜鸟教程、尚硅谷。 JavaScript 快速入门手册 &#x1f4af; 前言&#xff1a; 本人目前算是一个Java程序员&#xff0c;但是目前环境… ε(ο&#xff40;*))) 一言难尽啊&#xff0c;blog也好久好久没有更新了&#xff0c;一部分工作原因吧(外包真…

重新认识小米

被镁光灯聚焦的企业&#xff0c;总是会被贴上各种标签。 8月14日&#xff0c;小米科技创始人雷军以“成长”为主题的年度演讲&#xff0c;刷遍社交网络。提到小米&#xff0c;你首先想到什么&#xff1f;手机发烧友、极致性价比&#xff0c;还是最年轻的500强&#xff1f; 这…

八大排序算法 - Java实现

冒泡排序 排序原理&#xff1a; 比较相邻的元素。如果前一个元素比后一个元素大&#xff0c;就交换这两个元素的位置。对每一对相邻元素做同样的工作&#xff0c;从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值 代码实现&#xff1a; import java.uti…

uniapp从入门到精通(全网保姆式教程)~ 别再说你不会开发小程序了

目录 一、介绍 二、环境搭建&#xff08;hello world&#xff09; 2.1 下载HBuilderX 2.2 下载微信开发者工具 2.3 创建uniapp项目 2.4 在浏览器运行 2.5 在微信开发者工具运行 2.6 在手机上运行 三、项目基本目录结构 四、开发规范概述 五、全局配置文件&#xff0…

大数据面试题:Spark的任务执行流程

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;1&#xff09;Spark的工作流程&#xff1f;2&#xff09;Spark的调度流程&#xff1b;3&#xff09;Spark的任务调度原理&#xf…

【BASH】回顾与知识点梳理(三十二)

【BASH】回顾与知识点梳理 三十二 三十二. SELinux 初探32.1 什么是 SELinux当初设计的目标&#xff1a;避免资源的误用传统的文件权限与账号关系&#xff1a;自主式访问控制, DAC以政策规则订定特定进程读取特定文件&#xff1a;委任式访问控制, MAC 32.2 SELinux 的运作模式安…

VMware 虚拟机三种网络模式详解

文章目录 前言桥接模式(Bridged)桥接模式特点: 仅主机模式 (Host-only)仅主机模式 (Host-only)特点: NAT网络地址转换模式(NAT)网络地址转换模式(NAT 模式)特点: 前言 很多同学在初次接触虚拟机的时候对 VMware 产品的三种网络模式不是很理解,本文就 VMware 的三种网络模式进行…

Vue 项目搭建

环境配置 1. 安装node.js 官网&#xff1a;nodejs&#xff08;推荐 v10 以上&#xff09; 官网&#xff1a;npm 是什么&#xff1f; 由于vue的安装与创建依赖node.js&#xff08;JavaScript的运行环境&#xff09;里的npm&#xff08;包管理和分发工具&#xff09;&#xff…

创建密码库/创建用户帐户/更新 Ansible 库的密钥/ 配置cron作业

目录 创建密码库 创建用户帐户 更新 Ansible 库的密钥 配置cron作业 创建密码库 按照下方所述&#xff0c;创建一个 Ansible 库来存储用户密码&#xff1a; 库名称为 /home/curtis/ansible/locker.yml 库中含有两个变量&#xff0c;名称如下&#xff1a; pw_developer&#…

k8s 常见面试题

前段时间在这个视频中分享了 https://github.com/bregman-arie/devops-exercises 这个知识仓库。 这次继续分享里面的内容&#xff0c;本次主要以 k8s 相关的问题为主。 k8s 是什么&#xff0c;为什么企业选择使用它 k8s 是一个开源应用&#xff0c;给用户提供了管理、部署、扩…

iPhone(iPad)安装deb文件

最简单的方法就是把deb相关的文件拖入手机对应的目录&#xff0c;一般是DynamicLibraries文件夹 参考&#xff1a;探讨手机越狱和安装deb文件的几种方式研究 1、在 Mac 上安装 dpkg 命令 打包 deb 教程之在 Mac 上安装 dpkg 命令_xcode打包root权限deb_qq_34810996的博客-CS…

SystemVerilog之接口详解

1.入门实例 测试平台连接到 arbiter的例子&#xff1a;包括测试平台, arbiter仲裁器, 时钟发生器 和连接的信号。 ㅤㅤㅤ ㅤ ㅤㅤㅤㅤㅤ Arbiter里面可以自定义发送的权重&#xff0c; 是轮询还是自定义 grant表示仲裁出来的是哪一个&#xff0c;也即只有0&#xff0c;1&am…

HTML笔记(3)

表单标签 用于登录、注册界面&#xff0c;以采集用户输入的信息&#xff0c;把信息采集到之后&#xff0c;用户一点按钮&#xff0c;就会把这些信息发送到服务端&#xff0c;服务端就可以把这些数据存储到数据库&#xff0c;所以表单是一个非常重要的html标签&#xff0c;它主要…

基于Opencv的虚拟拖拽项目

预备知识 勾股定理 跟随移动算法 手势识别图解 项目源代码 """ 演示一个简单的虚拟拖拽 步骤&#xff1a; 1、opencv 读取视频流 2、在视频图像上画一个方块 3、通过mediapipe库获取手指关节坐标 4、判断手指是否在方块上 5、是&#xff0c;方块跟着移动 6、…

SLAM-VIO视觉惯性里程计

SLAM 文章目录 SLAM前言IMU与视觉比较单目视觉缺陷&#xff1a;融合IMU优势&#xff1a;相机-IMU标定松耦合紧耦合基于滤波的融合方案&#xff1a;基于优化的融合方案&#xff1a; 前言 VIO&#xff08;visual-inertial odometry&#xff09;即视觉惯性里程计&#xff0c;有时…

12_Redis为什么这么快高性能设计之epoll和IO多路复用深度解析

Redis为什么这么快&高性能设计之epoll和IO多路复用深度解析 一、before 多路复用要解决的问题 结论 二、IO多路复用模型 2.1 是什么 IO&#xff1a;网络IO多路&#xff1a;多个客户端连接&#xff08;连接就是套接字描述符&#xff0c;即socket或者channel&#xf…