system V——进程间通信

上一篇博客中我介绍了system V进程间通信中的内存共享,但是其中还有两
种通信方式:消息队列、和信号量,接下来我将简单介绍一下,消息队列和
信号量以及操作系统是如何看待system V进程间通信的。

1. 消息队列

a. 大致介绍

消息队列会维护一个队列,供两个进程进行进程间通信:它与共享内存不同的就是它的数据是存储在一个节点中,再次存储数据时再创建一个节点链入到顺序表或者链表构成的队列中,关于它的数据存储格式是在一个结构体中,但是这个结构体由用户自定义:
在这里插入图片描述
其中第一个成员是用户自定义的类型(例如我要自定义A进程存储进去的数据是A类型ATYPE,我们可以使用宏定义来进行)第二个是用户的存储数据,这个可以是一个数组也可以是一个结构体,而对于数据的访问方式,那自然是由第一个成员的类型来让用户决定的。所以假如我们要让两个进程实现进程间通信的话,使用内存共享我们可能不太方便区分共享内存中的数据究竟是谁要接收,使用消息队列的话我们可以自定义数据的访问方式,当我们需要A进程提取B进程的消息时,我们就可以在队列中遍历寻找数据类型为B进程所时使用的类型,这样就可以区分数据是谁发送供谁使用了:
在这里插入图片描述

b. 函数接口

消息队列的函数接口大致与共享内存的接口形式上差不多,依旧是:
msgget
在这里插入图片描述
消息队列的数据发送:
在这里插入图片描述
消息队列的删除:
在这里插入图片描述
其中删除消息队列的方式仍旧是IPC_RMID。
命令行中使用ipcs -q可以查看系统中的消息队列
ipcrm -q + msgid可以删除消息队列
操作系统中也会存在许多的消息队列,那么消息队列也需要被管理仍旧是先描述后组织。
以上就是消息队列的大致认识

2. 简单认识信号量

我们在认识共享内存的时候我们发现共享内存是不安全的,它没有管道那样的同步机制,只要进程可以挂接上它,那么那个进程就可以随意的访问共享内存。这就会导致可能这个进程还在往进写数据时,另一个进程就开始读了。这样使得两个进程做的工作都没有了意义。
所以共享资源的使用是需要被保护起来的,就有了互斥和同步。

互斥:任何一个时刻只允许一个执行流访问共享资源
同步:多个执行流访问共享资源时,按照一定顺序访问

保护共享资源,其实也可以理解为保护代码中使用共享资源的代码段,只要将这一段代码维护好了,那么共享资源也就被维护好了,因为共享资源的使用也不就是通过代码来使用的嘛。所以我们将共享资源叫做临界资源,而访问临界资源的代码叫做临界区。对临界资源的保护就转化成了临界区的保护。
在这里插入图片描述
在接口中信号量的创建接口中,第二个参数是创建多少个信号量,因为我们的共享资源申请时虽然是一大片,但是使用时可能是多个部分,所以需要多个信号量。创建出来的多个信号量,我们也叫信号量集。
信号量的本质其实就是一个计数器,你可以理解为信号量中有一个整型,它表示了共享资源中可使用资源的数量。当有进程访问这个整形就–,当使用完成该部分共享资源时这个整形就会++。
这样当我们使用信号量保护我们的共享资源之后,如果有进程需要访问我们的共享资源,我们首先需要看到信号量中的那个整形是否大于0,如果大于0,那么我们这个进程就可以开始访问共享资源,同时整形–。如果整形等于0,那么此时访问信号量的进程就会被阻塞挂起,直到共享资源中有可用的资源。
这个时候我们就可以保护共享资源了:
在这里插入图片描述
而当信号量中的整形最大是1,意味着该整形只有两种状态0或1,那就表示该信号量所保护的资源同一时间只能由一个进程访问使用,而这种保护机制就叫互斥,也叫加锁,加了互斥锁。
上面说到,信号量可以理解为其中有一个整形,用来记录可访问共享资源的数目,那么这个整形也就意味着必须能够被不同进程能够看到,那么就说明它不是属于某一个进程中的资源。而是操作系统提供的资源。不同进程看到了同一份资源,这不就是进程间通信嘛。所以信号量也是进程间通信,也是共享资源。那么它也需要被保护啊。所以我们对信号量的操作是原子性的,在对他的操作中只有++和–,–只有成功和不成功。也就是对信号量的操作中只有不执行和执行后必须完成两种状态这种原子操作,这样也算是保护了自己。
通过使用信号量,可以有效地控制对共享资源的访问,避免了数据竞争和冲突,确保了线程或进程之间的安全协作。

3. 操作系统对system V进程间通信的看法

经过以上的认识我们可以看到,system V进程间通信不像管道一样使用了旧的文件系统的接口来实现的,它是全新的一个部分,是独立于内存管理、文件管理、驱动管理、进程管理的。当我们观察三个通信控制接口时,都会发现,当使用特定命令操作时,它们都会提供各自的暴露给用户的数据结构:
共享内存:
在这里插入图片描述
消息队列:
在这里插入图片描述
信号量:
在这里插入图片描述
前面说了这些通信资源也是需要被管理的,那么管理的方式依旧是通过将它们抽象成结构体,然后通过数据结构组织起来,而以上的各个结构体是操作系统暴露给用户供用户使用的对资源的属性或者内容修改的部分。这些结构体是内核数据结构中的子集。而在这些结构体中我们发现它们后缀为_ds的结构体中第一个成员都是一个类型为struct ipc_perm的结构体,而这其中就记录着一个属性key,这个key就是用户所传入的参数key,也是操作系统识别通信资源的依据。
而在操作系统内核中,有一类型为struct ipc_ids的结构体,其中有一个成员entries,它是一个指针,它的类型是struct ipc_id_ary。struct ipc_id_ary中有一个柔性指针数组,这个数组中存储着一个结构体,它的类型是struct kernel_ipc_perm看起来和向上面的通信资源结构体的ipc_perm很像,其实内核中的管理通信资源的结构体也是像以上的设计,它们各种通信方式的结构体的开头成员都是kernel_ipc_perm,这样就可以通过柔性数组访问到任何一种通信方式的结构体,从而对通信资源实行管理。而访问通信资源的结构体我们只需要通过key遍历柔性数组的元素,找到之后判断出它是哪种通信方式,然后对这个kernel_ipc_perm结构体取地址,强转成对应的通信资源结构体
,这样就可以访问到目标通信资源结构体了。
在这里插入图片描述
这样假如这个数组中的第二个元素是共享内存的kennel_perm,我们要访问它就可以这样:

(struct shmid_ds*)p[1]->...

这种方式不就是C语言版的多态吗?
这样就能访问到每一个通信资源结构体了。操作系统也就是使用这样的结构来通过一个数组管理好所有的通信结构体。

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

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

相关文章

Python:解析数组二分查找算法bisect

简介:bisect模块提供对维护一个已排序列表而无须在每次插入后对该列表重排序的支持。对于具有大量条目需要大量比较运算的长列表,这改进了原来的线性搜索或频繁重排序。之所以被命名为 bisect 是因为它使用了基本的二分算法来完成任务。 不同于其他搜索特…

MOCO动量编码

参考,推荐阅读 李沐论文精读系列三:MoCo、对比学习综述(MoCov1/v2/v3、SimCLR v1/v2、DINO等)_moco 对比学习-CSDN博客 背景 1. MOCO CVPR 2020 2. 对比学习:无监督学习的一种,重点学习同类实例中的共同…

【教3妹学编程-算法题】使数组异或和等于 K 的最少操作次数

3妹:2哥,新年好鸭~ 2哥 : 新年好,3妹这么早啊 3妹:是啊,新年第一天要起早,这样就可以起早一整年 2哥 :得,我还不了解你,每天晒到日上三竿 3妹:嘿嘿嘿嘿,一年是…

分享88个表单按钮JS特效,总有一款适合您

分享88个表单按钮JS特效,总有一款适合您 88个表单按钮JS特效下载链接:https://pan.baidu.com/s/1v-qcl8bv2kxZ8a98Xo9UAg?pwd8888 提取码:8888 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气,…

Python解决SSL不可用问题

参考:https://blog.csdn.net/weixin_44894162/article/details/126342591 一、问题描述: 报错概述: WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. ## 警告:pip配…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(4)深度学习和机器学习

关于深度学习和机器学习,出来包含关系之外,还有如上总结的知识点。 分别从特征处理、学习方法、数据依赖、硬件依赖等4个方面,进行了总结。 从特征处理上看:深度学习从数据中习得高级特征,并自行创建新的特征。这比普…

并发容器+并发队列【ConcurentHashMap、CopyOnWriteArrayList、阻塞队列、ArrayBlockingQueue】

并发容器 什么是并发容器?同步容器:并发容器: ConcurrentHashMap结构图JDK1.7结构图JDK1.8结构图 CopyOnWriteArrayList实现原理 并发队列阻塞队列ArrayBlockingQueue 转自极客时间 什么是并发容器? 在JUC包中,有一大部分是关于并发容器的,如Concurr…

《21天精通IPv4 to IPv6》第4天:理解IPv6子网划分规则——如何为不同的系统划分IPv6子网?

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

基于javaEE的ssm仓库管理系统

仓库管理系统的重中之重是进销存分析这一板块,在这一板块中,顾名思义能够查询到近期的进货记录,包括每日的进货单据,单品推移(即某一商品的库存变化),方便我们核对库存差异。同时也需要查询到每日的销售数据&#xff0…

深入学习Pandas:数据连接、合并、加入、添加、重构函数的全面指南【第72篇—python:数据连接】

深入学习Pandas:数据连接、合并、加入、添加、重构函数的全面指南 Pandas是Python中最强大且广泛使用的数据处理库之一,提供了丰富的函数和工具,以便更轻松地处理和分析数据。在本文中,我们将深入探讨Pandas中一系列数据连接、合…

Python常用模块

前言 在使用Python进行开发时,会经常使用到不同的模块来帮助我们完成某部分功能的实现,因此掌握一些常用模块的常用方式可以帮助我们加速程序开发。 time模块 在Python中通常有以下几种方式来表示时间: 1.时间戳(timestamp),表示的是从1970年1月1日0…

第一篇【传奇开心果微博文系列】Python微项目技术点案例示例:pillow库实现毛笔字春联

传奇开心果微博文系列 系列微博文目录Python微项目技术点案例示例系列 微博文目录一、微项目目标二、实现微项目编程思路三、初步实现目标示例代码四、添加背景色、边框、阴影效果示例代码五、添加花纹背景、装饰线条示例代码六、添加花朵、插图等示例代码 系列微博文目录 Pyt…