进程间通信——共享内存

在我的管道博客中曾说过关于进程间通信有很多的方式,管道是利用了Linux
内核原有的接口而创造的,且它只支持单向通信。那么既然有用了原来本来
就有的资源而创造的进程间通信方式,那么也有新创造的通信方式,其中就
有内存共享、消息队列、信号量。它们都是基于system V命名空间的一些常
见的进程间通信方式,而我今天着重介绍,内存共享。

文章目录

  • 1. 共享内存的大致原理
  • 2. 共享内存接口
  • 3. 共享内存进程间通信
  • 4. 共享内存的特点

1. 共享内存的大致原理

我们说过,进程间通信的本质就是让不同的进程能够看到同一份资源,这样就提供了进程间通信的基础,而共享内存也是如此:
共享内存就是再物理内存中申请一片空间然后,如果有两个进程想要通信,那么就可以通过页表挂接到地址空间中,这样两个进程就能看到同一片资源。这样就可以通过对这片空间进行读写就可以了:
在这里插入图片描述

2. 共享内存接口

知道了大致原理,我们就来通过共享内存的接口来更加深层次的认识共享内存:
在这里插入图片描述
shmget是进程在物理内存中开辟空间的接口,它会返回一个整形,用来供用户识别共享内存。

第一个参数可以随意填写,它相当于是共享内存的标识,系统就是使用它来识别共享内存的
第二个参数就是共享内存的大小,这个大小建议是4096字节的整数倍(因为数据块的基本单元就是4KB)
第三个参数是用来创建或者获取共享内存的标志位,就两个标志位
	IPC_CREAT:使用它之后,如果key对应的共享内存不存在则创建,存在则返回共享内存的信息shmid
	IPC_EXCL:如果key对应的共享内存已经创建出来就报错(-1被返回),这个标志位可以确保共享内存是新创建的

使用它之后我们就可以开辟出一片空间,在命令行中我们可以使用ipcs -m来查看我们建立好的共享内存:
在这里插入图片描述
这个数字是我瞎写的:
在这里插入图片描述
需要介绍一下这其中的有些参数

key和shmid就是我们代码中的key和shmid
perm是这个共享内存的权限(它的权限跟文件的权限一样)
nattch是有多少个进程挂接到这个共享内存

而且我们看到我们的程序在创建号共享内存后直接就退出了,但是共享内存还存在。共享内存的生命周期是随内核的,意思就是当我们关闭我们的主机时,我们的共享内存才会关闭,而匿名管道文件的生命周期是随进程的。
关于共享内存的权限我们可以在shmget中设置:
在这里插入图片描述
在这里插入图片描述
我们可以使用ipcrm -m + shmid来释放掉这个共享内存。

在这里插入图片描述
可以看到上面那个key就是我们接口中调用时的参数。需要注意的是,这个接口仅仅是帮我们创建出了共享内存,所以我们还要认识两个接口shmat和shmdt:
在这里插入图片描述
shmat是用来让进程的地址空间通过页表与共享内存挂接的。这样我们的进程才能使用其中共享内存。

shmat的第一个参数就是shmget所返回的供用户辨别的shmid
第二个参数是传一个地址,将它定为我们虚拟地址中共享内存的地址(这里一般就是传空指针,让操作系统自行决定)
第三个参数是关于对这个共享内存的读或者写的标志位,但是我们有了权限的约束,也不太需要这个

shmdt是用来让进程与共享内存解链接的,它的参数很简单就是shmat所返回来的那个地址即可,我们可以写一小段代码来观察一下:

在这里插入图片描述

在这里插入图片描述
还有一个接口是在代码中对共享内存进行释放的shmctl:
在这里插入图片描述
在这里插入图片描述
这个接口的第三个参数我们稍后再介绍。这是一个控制共享内存的接口,而当它的命令cmd是IPC_RMID时,它就是释放共享内存:
在这里插入图片描述

这就是关于共享内存的接口使用,直到现在我们只是实现了进程间通信的前置部分,接下来我们看看,共享内存是如何实现进程间通信的。

3. 共享内存进程间通信

在实现进程间通信前我们先要有一些储备知识。在我们的操作系统的不只是我们的进程需要进程间通信,会有许多的进程需要进程间通信,这就会造成共享内存会很多,多就需要被管理,那还是先描述再组织,将共享内存的属性信息抽象成结构体然后通过数据结构给组织起来,这样操作系统对共享内存的管理就变成了对这个数据结构的增删查改,那操作系统是怎么辨别共享内存的呢?前面说过,shmget中所使用的key就是操作系统用来分辨共享内存的标志。
我们现在可以创建共享内存也可以挂接它,还能删除它,那假如我们的A进程创建挂接好共享内存后,我们的B进程想要跟A进程通信,怎么办呢?这还是用到了key,shmget中IPC_CREAT选项是当共享内存不存在时创建,存在时返回对应的shmid。所以我们就可以使用我们的key来找到我们的目标共享内存,但是我们自己定义的key不够随机,操作系统中的共享内存可能会很多,这个时候就要介绍另一个函数ftok:
在这里插入图片描述
它是一个类似于字符串哈希的方式通过传入一个字符串(经常是路径,因为路径具有唯一性)和一个自定义的整形通过这两者来给我们创建一个一定程度上唯一的整形供我们用作key。那么现在我们就可以,进行进程间通信了:
首先我们需要一些共享的信息放在一个头文件中:
在这里插入图片描述
其次就是我们的发送信息端:
在这里插入图片描述
接收消息端:
shmget就只需要IPC_CREAT就可以了,或者0也可以:
在这里插入图片描述
关于共享内存的释放就是谁创建谁释放。
下面我们简单的写一个通信代码:
发送端:
在这里插入图片描述
接收端:
在这里插入图片描述
在这里插入图片描述

在这里我们发现一些事情:读端不管内存中有没有数据,我只负责读,而且读过的数据还存在(跟数组一样)。这就是共享内存的其中一个特点,就是它不跟管道一样,它没有提供同步机制。可以说是想怎么样就怎么样,非常的不安全,我们这里就可以使用管道的同步机制来限制它,让共享内存也拥有同步的那么个意思:
使用命名管道:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 共享内存的特点

经过上面的介绍,我们也能够得出一些共享内存的一些特点:

1. 共享内存的通信方式,不会提供同步机制,使用时一定要注意共享内存的使用安全问题
2.共享内存是所有进程间通信,速度最快的(减少数据拷贝问题)
3. 共享内存可以使用较大空间

关于速度最快这一方面,我们在使用管道的时候,我们要将一个字符串从一个进程传输给另一个进程,首先需要我们的write有一个缓冲区,然后从这个缓冲区中拷贝到管道文件的缓冲区中,然后传输给我们另一个进程的read的缓冲区中。但是共享内存可没有管道文件缓冲区的概念,我们要将一个字符串从一个进程传给另一个进程,我们可以直接在A进程中将字符串放进去,然后这个数据直接就是我们B进程的了,不需要再将数据拷贝到我们的B进程中,缺少了文件页缓冲区拷贝的那一环。那此时我们的A进程的数据直接放在共享内存中呢?连A进程的拷贝到共享内存中的过程也少了,相比于管道文件只直接少了两次拷贝,提高了进程间通信效率,这也就是为什么共享内存是所有进程间通信最快的了。

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

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

相关文章

UDP是什么,UDP协议及优缺点

UDP,全称 User Datagram Protocol,中文名称为用户数据报协议,主要用来支持那些需要在计算机之间传输数据的网络连接。 UDP 协议从问世至今已经被使用了很多年,虽然目前 UDP 协议的应用不如 TCP 协议广泛,但 UDP 依然是…

飞天使-k8s知识点14-kubernetes散装知识点3-Service与Ingress服务发现控制器

文章目录 Service与Ingress服务发现控制器存储、配置与角色 Service与Ingress服务发现控制器 在 Kubernetes 中,Service 和 Ingress 是两种不同的资源类型,它们都用于处理网络流量,但用途和工作方式有所不同。Service 是 Kubernetes 中的一个…

C++2024寒假J312实战班2.5

题目列表: #1多项式输出 #2龙虎斗 #3表达式求值 #4解密 #1多项式输出 这是第一个题目很简单,我也作对了。 我们下来看一下题目: 我们先来看一下样例: 5 100 -1 1 -3 0 10 首先100是第一项,所以不输出加号&…

4.2 Verilog 过程赋值

关键词:阻塞赋值,非阻塞赋值,并行 过程性赋值是在 initial 或 always 语句块里的赋值,赋值对象是寄存器、整数、实数等类型。 这些变量在被赋值后,其值将保持不变,直到重新被赋予新值。 连续性赋值总是处…

大数据应用对企业的价值

目录 一、大数据应用价值 1.1 大数据技术分析 1.2 原有技术场景的优化 1.2.1 数据分析优化 1.2.2 高并发数据处理 1.3 通过大数据构建新需求 1.3.1 智能推荐 1.3.2 广告系统 1.3.3 产品/流程优化 1.3.4 异常检测 1.3.5 智能管理 1.3.6 人工智能和机器学习 二、大数…

Java写标准输出进度条

学Java这么久了,突发奇想写一个 进度条 玩玩,下面展示一下成功吧! Java代码实现如下 public class ProcessBar {public static void main(String[] args) {//进度条StringBuilder processBarnew StringBuilder();//进度条长度int total100;/…

Adb显示第3方应用的包名原理

Android早期版本实现原理请看 Android源码分析-pm命令的实现,列出包名pm list package,列出系统库pm list libraries_pm list packages-CSDN博客 Android12 对adb shell pm 实现原理做了重构:改成了template模式PackageManagerShellCommand …

备战蓝桥杯---动态规划之经典背包问题

看题: 我们令f[i][j]为前i个物品放满容量为j的背包的最大价值。 f[i][j]max(f[i-1][j],f[i-1][j-c[i]]w[i]); 我们开始全副成负无穷。f[0][0]0;最后循环最后一行求max; 负无穷:0xc0c0c0c0;正无穷:0x3f3f3f3f 下面是v12,n6的图示&#xff…

如何开发一个游戏平台?

随着科技的进步和互联网的普及,游戏行业正在迅速发展。游戏平台的开发已成为游戏行业的一个重要组成部分。开发一个游戏平台需要深入了解游戏行业,掌握相关技术,并具备创新思维。以下是一些关于如何开发一个游戏平台的建议: 市场调…

1、学习 Eureka 注册中心

学习 Eureka 注册中心 一、创建 Eureka 微服务0、SpringBoot 和 SpringCloud 版本1、引入 Eureka 服务端依赖2、启动类加 EnableEurekaServer 注解3、配置 yaml 文件,把 Eureka 服务注册到 Eureka 注册中心4、访问 Eureka 服务端,查看注册中心的服务列表…

立体感十足的地图组件,如何设计出来的?

以下是一些设计可视化界面中的地图组件更具备立体感的建议: 使用渐变色: 可以使用不同的渐变色来表现地图的高低差异,例如使用深蓝色或深紫色来表示海底,使用浅绿色或黄色来表示低地,使用橙色或红色来表示高地。 添加…

【linux系统体验】-archlinux折腾日记

archlinux 一、系统安装二、系统配置及美化2.1 中文输入法2.2 安装virtualbox增强工具2.3 终端美化 三、问题总结3.1 一、系统安装 安装步骤人们已经总结了很多很全: Arch Linux图文安装教程 大体步骤: 磁盘分区安装 Linux内核配置系统(基本软件&…

Bean 的六种作用域

Bean 的六种作用域 .Bean的作用域属性注入和content获取Bean单例作用域:http://127.0.0.1:8080/single1多例作用域: http://127.0.0.1:8080/prototype请求作用域: http://127.0.0.1:8080/request会话作用域: http://127.0.0.1:8080/sessionApplication作用域: http://127.0.0.1…

python 爬虫篇(3)---->Beautiful Soup 网页解析库的使用(包含实例代码)

Beautiful Soup 网页解析库的使用 文章目录 Beautiful Soup 网页解析库的使用前言一、安装Beautiful Soup 和 lxml二、Beautiful Soup基本使用方法标签选择器1 .string --获取文本内容2 .name --获取标签本身名称3 .attrs[] --通过属性拿属性的值标准选择器find_all( name , at…

2003-2021年地级市实际利用外资数据/地级市实际利用FDI数据

2003-2021年地级市实际利用外商直接投资数据/地级市FDI数据 1、时间:2003-2021年 2、来源:城市年鉴、统计公报、省统计年鉴,已尽最大程度进行填补 3、指标:省份代码、城市代码、省份、城市、年份、当年实际使用外资金额&#x…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏15(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言实现树倒下的效果拾取圆木砍树消耗卡路里斧头手臂穿模问题处理源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中&…

新春贺词 | 人大金仓笃行不怠,初心不改!

新春贺词 冬至阳生,岁回律转,在这岁律更新的美好时刻,谨向长期以来关心和支持金仓发展的用户、领导和朋友们致以诚挚的问候和感谢!向一年来为了金仓事业发展奋战拼搏的全体金仓人及家属致以美好的新春祝福! 回首2023&a…

Bert下载和使用(以bert-base-uncased为例)

Bert官方github地址:https://github.com/google-research/bert?tabreadme-ov-file 【hugging face无法加载预训练模型】OSError:Can‘t load config for ‘./bert-base-uncased‘. If you‘re trying 如何下载和在本地使用Bert预训练模型 以bert-base-u…

多 split 窗口 in Gtkmm4

文章目录 效果预览实现概要源代码 效果预览 实现概要 使用Gtk::Paned虽然 Paned 只能装两个子控件, 但是我可以嵌套 paned1 装 box1 和 box2 paned2 装 paned1 和 box3 源代码 #include <gtkmm.h> class ExampleWindow : public Gtk::Window { public:ExampleWindow()…

二阶系统的迹-行列式平面方法(trace-determinant methods for 2nd order system)

让我们再次考虑二阶线性系统 d Y d t A Y \frac{d\mathbf{Y}}{dt}A\mathbf{Y} dtdY​AY 我们已经知道&#xff0c;分析这种二阶系统。最主要的是注意它的特征值情形。 &#xff08;此处没有重根的情形&#xff0c;所有是partial&#xff09; 而特征值&#xff0c;也就是系…