进程间通信-system V共享内存

news2024/11/18 13:35:46

在这里插入图片描述

文章目录

  • 1. system V共享内存
    • 1.1 共享内存示意图
  • 2. 共享内存函数
    • 2.1 shmget函数
    • 2.2 代码实现
      • 2.2.1 shmat
      • 2.2.2 shmdt
  • 3. 信息量

1. system V共享内存

system V的意思是一套标准,共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。

1.1 共享内存示意图

在这里插入图片描述
这是两个互不相关的进程,如果有一个共享内存。
第一步:在物理内存中创建一块空间
在这里插入图片描述
第二步:通过页表把物理内存映射到进程地址空间的共享区

2. 共享内存函数

2.1 shmget函数

在这里插入图片描述
第二个参数我们一般建议设置成为页(4KB)的整数倍
假设我们的内存是4GB,那么就会有2的20次方个页。那么这么多页就会被管理起来(struct page)。

第三个参数意思是:看共享内存存不存在
常用的宏标记
在这里插入图片描述
IPC_CREAT:创建共享内存,如果已经存在,就获取之,不存在,就创建之

IPC_EXCL:不单独使用,必须和IPC_CREAT配合使用。如果不存在指定的共享内存,创建之,如果存在,就出错返回
IPC_EXCL意义是:可以保证,如果shmget函数调用成功,一定是一个全新的共享内存

那么共享内存存在哪里
因为在内存中,会有大量的进程进行通信,那么就会有大量的共享内存。那么共享内存也会被管理起来(struct shmid_ds),它里面包含了共享内存的的属性(权限,id等),它里面有个struct ipc_perm(权限),里面包含了key,也就是shmget第一个参数(共享内存的唯一性)。

为什么这个参数需要用户自己提供
因为我们可以约定好用同一个key,让进程可以看到同一份资源。

那么我们如何设置key呢
在这里插入图片描述
可以用这个函数来创建唯一的key值。

pathname:该路径是必须存在的,ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置

proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255

2.2 代码实现

在这里插入图片描述
我们在这创建两个进程,让IpcShmSer充当创建共享内存的角色,让IpcShmCli充当使用共享内存的角色。

然后我们需要写一个创建key的函数,并且能让这两个进程都能看到:
在这里插入图片描述
我们创建一个Comm.hpp来完成这项工作。
在这里插入图片描述
这里我们再创建一个.hpp来打印信息,可以更好的去调试。
在这里插入图片描述
我们可以先看一下这样写的结果:
在这里插入图片描述
下一步,我们开始创建共享内存,现在我们有了key,再去设置一下共享内存的大小:
在这里插入图片描述
现在我们就在IpcShmSer里面把共享内存创建好:
在这里插入图片描述
运行结果:
在这里插入图片描述
从运行结果我们可以看出:当我们运行完毕创建全新的共享内存的代码后(进程退出),但是当后面再次运行时,代码无法运行,说明共享内存是存在的。所以它不像打开文件那样,进程退出,会自动刷新文件的缓冲区和关闭文件。而共享内存不会退出。所以我们得到的结论是:system V下的共享内存,生命周期是随内核的,如果我们不显示的删除,那么只能通过操作系统重启来解决

那么我们怎么查看当前用户有哪些IPC资源呢
在Linux下,有一个命令:ipcs -m
在这里插入图片描述
这里nattch的意思是:映射进程的数量。perms的意思是:权限为多少。
这里权限为0,说明没有人能访问它,我们需要设置一下。
在这里插入图片描述
那么我们怎么显示删除呢
方法一:通过命令:ipcrm -m shmid
在这里插入图片描述
为什么删除的是shmid,而不是key呢
key是操作系统内部的唯一标识符,而shmid是用户层的,ipcrm也是用户层的命令,所以用的是shmid

方法二:通过系统接口进行删除
在这里插入图片描述
第二个参数常用的是:IPC_RMID:从系统中删除由shmid标识的共享内存区

如果我们用了IPC_RMID,那么第三个参数设置成空。
在这里插入图片描述

2.2.1 shmat

现在我们就需要使用共享内存,在使用它之前,我们需要将共享内存和自己的进程产生关联。
在这里插入图片描述
第二个参数:如果shmaddr 是NULL,系统将自动选择一个合适的地址
我们先学习这一种情况,其余情况以后再说。

第三个参数:默认为0的话,共享内存具有可读可写权限

shmat返回值是该段所连接的实际地址,如果出错返回 -1。
在这里插入图片描述

2.2.2 shmdt

在这里插入图片描述
在这里插入图片描述
完整代码
在这里插入图片描述
这是IpcShmSer的代码,下面我们就写IpcShmCli代码。
在这里插入图片描述
IpcShmCli不需要删除共享内存,因为和它没有关系。

下面我们就可以使用共享内存了,我们让客户端去写:
在这里插入图片描述
这里为什么不需要调用系统接口呢
我们把共享内存映射到我们的进程地址空间(堆,栈之间),对于每一个进程而言,挂接到自己的上下文中的共享内存,,属于自己的空间,类似于堆栈空间,可以被用户直接使用
在这里插入图片描述
IpcShmSer也是直接使用就可以了。下面我们看一下运行情况:
在这里插入图片描述
我们可以看到:先运行的IpcShmSer不管共享内存里面有没有数据,直接打印。
在这里插入图片描述
在这里插入图片描述
当我们运行IpcShmCli后,IpcShmSer就会开始打印出共享内存的数据。

从运行结果来看,共享内存,没有任何访问控制,不会被阻塞,可以直接通信,但是不安全

那么我们也可以从键盘上去输入到共享内存中:
在这里插入图片描述
能被多个进程看到的资源被称为临界资源
如果没有对临界资源进行任何保护,双方进程在进行访问的时候,就可能是乱序的,可能会因为读写交叉而导致的各种乱码,废弃数据,访问控制方面的问题

对多个进程而言,访问临界资源的代码叫做临界区
在这里插入图片描述
在这里插入图片描述
只有这两个黄色的叫做临界区。

我们把一件事情,要么没做,要么做完,没有中间状态叫做原子性

任何时刻,只允许一个进程,访问临界资源叫做互斥

3. 信息量

什么是信号量
在这里插入图片描述
信号量本质是一个计数器,它表示能有多少进程进临界资源里

信号量为1的时候,表现的就是互斥特性,也叫做二元信号量。常规信号量叫做多元信号量

所以,任何进程想要访问临界资源,必须先申请信号量,如果申请成功,就能访问临界资源中的一部分

每一个进程要申请信号量,前提是每一个进程都必须看到这个信号量,那么能被多个进程看见,说明信号量也是临界资源

前面我们知道信号量是可以保护临界资源的,那么信号量也是临界资源,谁来保护它呢

举个例子:
在这里插入图片描述
现在有一个变量cnt,我们想让cnt减减,它的一个过程是什么样的呢?
CPU首先会从内存中读取,然后在CPU中进行减减,减减完之后,再返回到内存中。
在这里插入图片描述
但是现在,当CPU进行第2步,还没有进行第3步的时候,又来一个进行进行程序替换会怎么样?
在这里插入图片描述
假设这个进程需要减50次,那么原来进程的数据就会保存到它的进程上下文中,去执行新的进程。
在这里插入图片描述
那么现在cnt就会变成50,但是当原来进程再继续执行的时候,会取出进程的上下文数据,cnt又变成了99。这样,就会造成数据混乱。所以,这里的cnt会有很多中间状态,不具备原子性。

但是,信号量是一个计数器,它对应的操作是有原子性的

那么信号量对应的操作是什么
信号量对应的操作是PV操作,P操作相当于减减,就是申请资源,V操作相当于加加,就是释放资源

内存共享没有访问控制,但是可以通过信号量来资源保护

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

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

相关文章

AI遇上建筑设计,是出圈还是翻车?

AIGC 落地,始于场景,终于价值。 去年以来出现了 AIGC 热潮,引发了 AIGC 及其应用话题的爆发性增长,不少人感慨强人工智能的时代已经离我们不那么遥远了。但是在热潮的另一面,我们看到真正能落地的场景依然是凤毛麟角&a…

【C语言】结构体指针

结构体指针 结构体基础知识注意对于成员的赋值 结构体指针指向结构体变量的指针结构体指针与结构体成员指针用结构体指针引用结构体成员 结构体 基础知识 初识结构体,可以先看这篇浅显易懂的文章结构体–基础篇 所谓结构体,是一组类型可以不同的相关变…

部署输配电线路火灾隐患排查治理

输电线路防山火在线监测装置 一、产品描述: 电力设施为了远离人们的生活区域选择部分扎根在森林里面,减少发生触电事故的发生。但是提到森林就不得不说其中一个山火问题,山火灾害对建设在森林的电力设施造成的损害不可预估,为保障…

CodeForces.1806A .平面移动.[简单][判断可达范围][找步数规律]

题目描述: 题目解读: 给定移动规则以及起始点,终点;分析终点是否可达,可达则输出最小步数。 解题思路: 首先要判定是否可达。画图可知,对于题目给定的移动规则,只能到达起始点(a,b…

Go 开发实践:手把手教你搭建一个登录功能

本文首发自「慕课网」 ,想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"及“慕课网公众号”! 作者:Codey|慕课网讲师 用 Go 语言搭建简易登录功能 如果你最近刚学习Go 语言基础特性,对 …

《深入理解BigDecimal:揭秘钱财计算的核心技术》

文章目录 《深入理解BigDecimal:揭秘钱财计算的核心技术》***\*一、BigDecimal概述\*******\*二、BigDecimal常用构造函数\****2.1、常用构造函数2.2、使用问题分析***\*三、BigDecimal常用方法详解\****3.1、常用方法3.2、BigDecimal大小比较***\*四、BigDecimal格式化\*****…

【正点原子STM32连载】 第二十章 基本定时器实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id609294757420 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第二十…

字符串匹配算法--KMP算法--BM算法

该算法解决的是字符串匹配问题,即查看字符串中是否含有完整的匹配字符串。如在java的string的contains方法匹配问题最简单的就是暴力破解了。在java的contains也是这么实现的,效率是低一点的。如果想要更快的速度可以自己写KMP算法。 代码实现体验 还未…

chatgpt赋能Python-python_numpy怎么用

Python与Numpy:简介 Python是一种高级编程语言,它具有简洁的语法和广泛的应用领域。Numpy是一个为Python提供高效数学库的开源库,它允许进行高速数值计算和数据处理。 对于那些正在开始使用Python和Numpy的初学者,这篇文章将向您…

CANoe使用教程

目录 1.CAN IG使用 2.Visual Sequence 自动发送报文序列,可以设置多个visual sequence,可用于重复的网络模拟和write窗口输出,比IG灵活,比CAPL简单 3.CANoe中的系统变量和环境变量都是一种用于存储和传递数据的变量,…

linux部署yolov5

Linux配置 LibTorch 和 OpenCV LibTorch 下载地址:https://pytorch.org/get-started/locally/ 直接解压即可 OpenCV 下载地址:https://opencv.org/releases/ 需要配置ffmpeg环境 export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/workspace/dengzr/li…

嵌入式Linux应用开发笔记:GPIO编程

文章目录 目的基础说明代码示例数字输出数字输入外部中断 总结 目的 GPIO嵌入式设备中最基础的外设,使用上也是非常频繁的。这篇文章将记录下应用程序中GPIO操作相关内容。 这篇文章中内容均在下面的开发板上进行测试: 《新唐NUC980使用记录&#xff1…

15、STM32驱动sht35温湿度传感器

本文使用模拟IIC驱动sht35温湿度传感器 踩坑点:购买的模块IIC上拉电阻为10KΩ,会导致IIC不稳定,抗干扰差,容易导致时序错误;建议更换为4.7KΩ 一、CubeMx配置 其余默认,生成工程 1、us精确延时 Delay_Dr…

2023年电子、通信与控制工程国际会议(SECCE 2023)

会议简介 Brief Introduction 2023年电子、通信与控制工程国际会议(SECCE 2023) 会议时间:2023年8月11日-13日 召开地点:韩国济州岛 大会官网:www.isecce.org 2023年电子、通信与控制工程国际会议(SECCE 2023)将围绕“电子、通信与控制工程”…

Spring Boot 整合流程引擎 Flowable(附源码地址)

一、导入依赖 flowable依赖&#xff1a; <dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.7.2</version> </dependency>pom.xml: <?xml version"1…

驱动页面性能优化的3个有效策略

目录 引言 背景 前端性能优化 测试视角的解法 性能问题的发现 性能数据的采集 性能指标的确定 性能问题的分析 如何衡量性能问题严重性 分析性能瓶颈-分析思路 分析结论关键思路 引言 测试通过发现、分析、验证三板斧&#xff0c;驱动推进页面性能优化快速有效&…

关注 | 蛙色元宇宙,正式成为XRMA联盟成员单位

中国虚拟现实与元宇宙产业峰会&#xff0c;2023年3月22日于杭州圆满结束&#xff0c;在杭州市人民政府、浙江省经济和信息化厅指导&#xff0c;由杭州市经济和信息化局、杭州市西湖区人民政府主办&#xff0c;中国信息通信研究院承办。 蛙色元宇宙作为元宇宙的领先企业之一&…

【AI面试】CrossEntropy Loss 、Balanced Cross Entropy、 Dice Loss 和 Focal Loss 横评对比

样本不均衡问题一直是深度学习领域一个不可忽略的问题&#xff0c;常说的长尾效应&#xff0c;说的就是这个问题。一类占据了主导地位&#xff0c;导致其他类无论怎么优化&#xff0c;都不能好转。 无论是纯纯的分类任务&#xff0c;还是稍微复杂一些的目标检测任务和分割任务…

关于java在成员/全局变量上不同类型赋值遇到的问题(值传递)

一个疑惑 文件简介回答参考文献 文件简介 class ss{static class Student{int id;String name; /*public Student(int id, String name) {this.id id;this.name name;}*/public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {…

数字人入门文章速览

语音驱动三维人脸方法 OPPO 数字人语音驱动面部技术实践 【万字长文】虚拟人漫谈 Blendshape学习笔记 人脸重建速览&#xff0c;从3DMM到表情驱动动画 功能强大的python包&#xff08;四&#xff09;&#xff1a;OpenCV 从Blendshapes到Animoji 3D人脸重建算法汇总 一、3D人脸重…