系统编程2(消息队列)

⦁ 消息队列概念

Linux系统中消息队列(Message Queue)是进程间通信的一种方式,这种通信机制的好处是可以传输指定类型(用户可以自行定义)的数据,相同类型的数据根据到达顺序在队列中进行排队。

当然,不同类型的数据不能处于同一个队列中,也就是说系统中可能存在多个消息队列,每个消息队列中的数据类型都是不同的,所以用户打算读取消息队列中的数据时也需要指定数据类型,才可以从存储该类型数据的消息队列中读取有效数据。

思考:既然Linux系统中可能存在多条消息队列,那操作系统是如何管理的以及进程如何选择某个消息队列来发送消息?

回答:Linux系统每个创建的消息队列都具有一个唯一的键值key,进程可以通过指定消息队列的键值来向消息队列发送数据。Linux系统中提供了一个shell命令:ipcs -a来查看系统中所有的IPC对象的信息。
在这里插入图片描述
⦁ 创建消息队列

思考:既然当前的Linux系统中不存在消息队列,那用户如何创建一个消息队列供进程访问?

回答:Linux系统提供了一个名称叫做msgget()的函数接口,用户利用该接口可以创建或者打开一个消息队列,同样Linux系统中提供了一个shell命令:ipcmk 可以用于创建IPC对象。

(1) ipcmk命令
在这里插入图片描述
在这里插入图片描述
(2) msgget()函数
在这里插入图片描述
(3) 函数参数
msgget函数有两个参数,第一个参数需要传入一个key_t类型的值,该值指的是要创建的消息队列的key键值,key也可以称为密钥。 键值类型key_t其实在内核源码中指的是int类型,如下图:
在这里插入图片描述
msgget()函数的第二个参数指的是创建消息队列的标志,其中IPC_CREAT指的是如果消息队列不存在则创建,IPC_EXCL指的是如果消息队列存在则表示函数调用失败。

另外,也可以指定消息队列的权限,权限的结构和open函数的mode类型,采用八进制表示,只不过消息队列不需要设置执行权限,所以权限设置为0644即可。

(4) 返回结果

msgget()函数调用成功,则返回消息队列的标识符,如果调用失败,则返回-1并设置错误码。

思考:可以看到调用msgget()函数需要传入一个键值key,这个键值key是否可以由用户指定?

回答:可以由用户指定,但是不建议这样操作,因为可能有多个进程都会创建消息队列,如果某两个进程指定的键值key相同,则会创建失败,所以应该由系统生成唯一的键值key。

Linux系统中提供了一个名称叫做ftok()的函数接口,利用该接口可以生成IPC对象的键值key,该接口的使用规则如下:

在这里插入图片描述
可以看到,ftok()函数可以把一个指定路径的文件和一个指定的项目id转换为一个system-V IPC对象使用的键值key。

(1) 函数参数

ftok()函数的第一个参数指的是系统中已经存在并且可以访问的一个文件的路径,用户可以指定一个文件,但是该文件必须存在且可以被访问,其实就是为了得到文件的属性信息中的inode编号和设备编号,因为Linux系统中一个文件的inode编号是唯一的。

ftok()函数的第二个参数指的是项目ID,这个可以由用户进行指定,虽然参数proj_id的类型是整型int,但是只会用到最低8it,所以这个参数的范围其实是1~255,因为这个参数的值必须是非0值。

(2) 返回结果

ftok()函数的返回值:当函数调用成功后,则返回生成的键值key,如果调用失败,则返回-1。

(3) 注意事项

在man手册中提到ftok()函数生成的键值key的组成:proj_id的低8位+ 设备编号的低8位+ inode编号的低16位。

练习:设计程序,在Linux系统中创建一个消息队列,并测试消息队列的键值key的组成是否正确。提示:可以通过stat()函数获取文件的属性信息。
在这里插入图片描述
⦁ 访问消息队列

思考:用户如果创建了一个消息队列,那进程如何向消息队列收发数据,数据类型如何指定?

回答:Linux系统中提供了一个名称叫做msgsnd()的函数接口,用户利用该函数可以向指定的消息队列发送消息,同时提供了一个名称叫做msgrcv()的函数接口,用户利用该接口可以从指定的消息队列中读取消息。
在这里插入图片描述
(1) 发送消息
在这里插入图片描述
可以知道,用户创建的消息队列是有默认容量的,默认容量是16384字节,可以通过msg.h得到,用户在向消息队列写入数据的时候要考虑消息队列的容量。
在这里插入图片描述
msgsnd函数的第一个参数msgid指的是消息队列的标识符,该标识符可以通过msgget函数得到。

msgsnd函数的第二个参数msgp指的是一个指向struct msgbuf类型的结构体指针,该结构体中有两个成员,其中一个成员mtype指的是消息类型,必须是一个大于0的正整数,另一个成员mtext指的是消息正文,类型可以是数组或者其他结构。

在这里插入图片描述
msgsnd函数的第三个参数msgsz指的是消息正文的大小,按字节计算,当然msgsz的值必须是非负整数,可以设置为0,表示消息正文的长度为0。

msgsnd函数的第四个参数msgflg指的是消息队列的标志,如果该标志设置为IPC_NOWAIT,则表示不阻塞,此时如果待写入的消息的长度大于消息队列剩余空间,则直接返回并报错。

注意:消息队列默认的属性是阻塞的,也就是当待写入的消息的长度大于消息队列剩余空间时,默认阻塞,直到消息队列的容量足够容纳时会解除阻塞。

(2) 读取消息

在这里插入图片描述
第一个参数:msgqid指的是MSG对象的标识符ID,MSG标识符可以通过msgget()函数获取。

第二个参数:msgp指的是存放消息的缓存地址,该地址下存储的是struct msgbuf结构体。

第三个参数:msgsz指的是存放消息的缓存的大小,按照字节计算,如果消息正文的大小大于用户设置的缓存大小,则根据msgflg是否为MSG_NOERROR进行判断,如果msgflg设置为MSG_NOERROR ,则可以读取对应字节的消息,如果msgflg没有设置,则无法读取消息并报错。

第四个参数:msgtyp指的是要接收消息的类型,在调用msgsnd函数时构造的消息结构体中有该成员的值。

  1. 等于0:指的是不区分类型,直接读取MSG中的第一个消息。

  2. 大于0:读取类型为指定msgtyp的第一个消息(若msgflg被配置了MSG_EXCEPT则读取除了类型为msgtyp的第一个消息)。

  3. 小于0:读取类型小于等于msgtyp绝对值的第一个具有最小类型的消息。例如当MSG对象中有类型为3、1、5类型消息若干条,当msgtyp为-3时,类型为3的第一个消息将被读取。

第五个参数:msgflg指的是接收消息选项,如果msgflg设置为0,指的是默认接收模式,在MSG中无指定类型消息时阻塞。

  1. IPC_NOWAIT :指的是非阻塞接收模式,当MSG中没有指定类型消息时直接退出函数
  2. MSG_EXCEPT :指的是读取除msgtyp之外的第一个消息。
  3. MSG_NOERROR:如果待读取的消息尺寸比msgsz大只返回msgsz部分,其余部分丢弃

⦁ 控制消息队列

IPC对象是一种持久性资源,如果没有明确的删除掉IPC对象,则IPC对象是不会自动从内存中消失的。用户除了可以使用命令的方式删除,也可以使用函数来删除。

Linux系统中提供了一个名称叫做msgctl的函数接口,用户可以利用该函数实现获取消息队列的属性信息、设置消息队列的属性信息、删除消息队列等操作。

  1. 指令删除
    在这里插入图片描述
  2. 函数删除
    在这里插入图片描述
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二)

Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二) 7. 实现条件WGAN-GP # 训练条件WGAN-GP def train_conditional_wgan_gp():# 用于记录损失d_losses []g_losses []# 用于记录生成样本的多样性(通过类别分…

python 微博爬虫 01

起因, 目的: ✅下载单个视频,完成。✅ 获取某用户的视频列表,完成。剩下的就是, 根据视频列表,逐个下载视频,我没做,没意思。获取视频的评论,以后再说。 关键点记录: 1. 对一个视…

Servlet、HTTP与Spring Boot Web全面解析与整合指南

目录 第一部分:HTTP协议与Servlet基础 1. HTTP协议核心知识 2. Servlet核心机制 第二部分:Spring Boot Web深度整合 1. Spring Boot Web架构 2. 创建Spring Boot Web应用 3. 控制器开发实践 4. 请求与响应处理 第三部分:高级特性与最…

vue中根据html动态渲染内容2.0

上次使用的是p标签用的contenteditable代替的可编辑的input,最后实现还是选择了用el-input的textarea方式。 一开始考虑的是需要根据用户输入自动撑开输入框,所以选择了p标签可编辑。 最后发现还是el-input会更好一点,只不过需要处理输入框撑…

CentOS 系统磁盘扩容并挂载到根目录(/)的详细步骤

在使用 CentOS 系统时,经常会遇到需要扩展磁盘空间的情况。例如,当虚拟机的磁盘空间不足时,可以通过增加磁盘容量并将其挂载到根目录(/)来解决。以下是一个完整的操作流程,详细介绍了如何将新增的 10G 磁盘…

LINUX基础 [二] - Linux常见指令

目录 💻前言 💻指令 🎮ls指令 🎮pwd指令 🎮whoami指令 🎮cd指令 🎮clear指令 🎮touch指令 🎮mkdir指令 🎮rmdir指令 🎮rm指令 &#…

基于php的成绩分析和预警与预测网站(源码+lw+部署文档+讲解),源码可白嫖!

摘要 人类现已迈入二十一世纪,科学技术日新月异,经济、资讯等各方面都有了非常大的进步,尤其是资讯与网络技术的飞速发展,对政治、经济、军事、文化、教育等各方面都有了极大的影响。 利用电脑网络的这些便利,发展一套…

《从底层逻辑剖析:分布式软总线与传统计算机硬件总线的深度对话》

在科技飞速发展的当下,我们正见证着计算机技术领域的深刻变革。计算机总线作为信息传输的关键枢纽,其发展历程承载着技术演进的脉络。从传统计算机硬件总线到如今备受瞩目的分布式软总线,每一次的变革都为计算机系统性能与应用拓展带来了质的…

Spring Boot 3.5新特性解析:自动配置再升级,微服务开发更高效

📝 摘要 Spring Boot 3.5作为Spring生态的最新版本,带来了多项令人振奋的改进。本文将深入解析其中最核心的自动配置增强特性,以及它们如何显著提升微服务开发效率。通过详细的代码示例和通俗易懂的讲解,您将全面了解这些新特性在…

【前端】webpack一本通

今日更新完毕,不定期补充,建议关注收藏点赞。 目录 简介Loader和Plugin的不同?(必会) 使用webpack默认只能处理js文件 ->引入加载器对JS语法降级,兼容低版本语法合并文件再次打包进阶 工作原理Webpack 的…

leetcode 264. Ugly Number II

动态规划解决。 关键是理解如何生成新的丑数。这道题和经典的斐波那契数列问题其实是一样的。求第n个数,需要用第n个数前面的数来求。不同的是,斐波那契数列不会重复。而本题的丑数,会重复出现。 class Solution { public:int nthUglyNumbe…

深入理解 HTML5 语义元素:提升网页结构与可访问性

引言 在构建网页的过程中,合理的结构与清晰的语义对于网页的质量、可维护性以及搜索引擎优化(SEO)都至关重要。HTML5 引入了一系列语义元素,为开发者提供了更精准描述网页内容的工具。本文将深入探讨 HTML5 语义元素的作用、使用…

PyCharm显示主菜单和工具栏

显示主菜单 新版 PyCharm 是不显示主菜单的,要想显示主菜单和工具栏,则通过 “视图” → “外观” ,勾选 “在单独的工具栏中显示主菜单” 和 “工具栏” 即可。 设置工具栏 此时工具栏里并没有什么工具,因此我们需要自定义工具…

CyclicBarrier 基本用法

CyclicBarrier 基本用法 简介 CyclicBarrier 是 Java 并发包(java.util.concurrent)中的一个同步辅助类。它允许一组线程相互等待,直到到达某个公共屏障点(common barrier point)。只有当所有参与的线程都到达屏障点…

[特殊字符] 手机连接车机热点并使用 `iperf3` 测试网络性能

好的,以下是根据你的描述整理出来的步骤及解释: 📶 手机连接车机热点并使用 iperf3 测试网络性能 本文将通过 iperf3 来测试手机和车机之间的网络连接性能。我们会让车机作为服务端,手机作为客户端,进行 UDP 流量传输…

FPGA上实现SD卡连续多块读的命令

在FPGA上实现SD卡连续多块读的命令 CMD17命令一次只能读取1个块 CMD18命令一次可以连续读取多个块,直到停止命令CMD12 CMD18命令读的块数程序可任意设置 目录 前言 一、SD卡多块读命令CMD18 二、停止读命令CMD12 三、SD卡初始化SD卡连续块读操作的verilog代码 …

DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…

NSGA-II 多目标优化 —— 理论、案例与交互式 GUI 实现

目录 NSGA-II 多目标优化 —— 理论、案例与交互式 GUI 实现一、引言二、NSGA-II 基本原理2.1 非支配排序2.2 拥挤距离2.3 算法流程三、数学模型与算法推导3.1 多目标优化问题描述3.2 非支配关系与排序3.3 拥挤距离计算四、NSGA-II 的优缺点4.1 优点4.2 缺点五、典型案例分析5.…

库学习04——numpy

一、基本属性 二、 创建数组 (一)arange a np.arange(10,20,2) # [10,12,14,16,18] 只有一个参数n的话,默认是从0到n-1的一维数组。 (二)自定义reshape a np.arange(12).reshape((3,4)) [[ 0 1 2 3][ 4 5 …

NVIDIA Jetson 快速切换CUDA版本| 多CUDA版本

当NVIDIA Jetson中安装了多个CUDA时,可以通过命令,快速切换不同版本的。 这样在环境变量和代码编译时,能使用指定版本的CUDA了。 本文适用于Jetson Nano、TX1/TX2、Xavier 和 Orin系列的设备,供大家参考。 cuda参考地址&#xf…