【深入学习Linux】System V共享内存

news2025/6/9 4:50:28

目录

前言

一、共享内存是什么?

共享内存实现原理

共享内存细节理解

二、接口认识

1.shmget函数——申请共享内存

 2.ftok函数——生成key值

再次理解ftok和shmget

1)key与shmid的区别与联系

2)再理解key

3)通过指令查看/释放系统中的ipc资源

3.shmctl函数——控制、释放共享内存

struct shmid_ds是什么

4.shmat函数和shmdt函数——对共享内存进行关联和去关联

三、共享内存的优缺点分析

总结



前言

早在设计Unix时,系统开发者就发现了一个悖论:在某些情况下,系统中的进程既要满足互相隔离又要彼此协同合作。

由此衍生出了System V IPC等通信方式,在保持进程独立性的前提下,通过内核中介、权限控制和同步机制实现安全通信。

System V IPC通信机制主要包括:消息队列/ 信号量/ 共享内存三种通信方式,本文主要讨论共享内存的概念原理以及使用方式。


一、共享内存是什么?

先来看看共享内存的概念:

通过让不同的进程看到同一块内存的方式,就被称为“共享内存”

在对共享内存的概念有了一定了解后,再来理解共享内存的原理。

共享内存实现原理

在不破坏进程独立性的前提下让两个进程通信,操作系统通过引入能让两个进程都能看到的同一份“资源”实现。对于共享内存,这份资源就是物理内存上的一段内存块。

以下阐述共享内存的原理。

共享内存细节理解

1)C/C++语言中的malloc等申请空间的函数能用于申请共享内存吗?

不能,malloc等函数申请的空间只属于该进程自己,不能被其他进程共享。共享内存机制是专门设计出来用于IPC进程间通信的。

2)共享内存是一种通信方式,想要通信的进程都可以使用。当两个进程希望进行通信时,可以使用已有的正在被其他进程使用的共享内存通信,也可以额外申请一块内存用于通信,根据实际需求决定。

3)系统中可能同时存在很多共享内存块。

二、接口认识

1.shmget函数——申请共享内存

 

2.ftok函数——生成key值

再次理解ftok和shmget

1)key与shmid的区别与联系

ftok函数返回值是key,shmget的返回值是shmid(共享内存标识符)。key与shmid的关系,有些类似于文件描述符fd与inode的关系,一个是应用进程层面使用的(shmid与fd),另一个是系统内核层面使用的(key与inode)。

2)再理解key

3)通过指令查看/释放系统中的ipc资源

删除共享内存指令:

 shmid可以通过上述ipcs指令查看。

3.shmctl函数——控制、释放共享内存

struct shmid_ds是什么

在shmctl函数的第三个参数中出现了struct shmid_ds结构体,该结构体是操作系统暴露给用户级的一种数据结构,他与操作系统为方便管理共享内存创建的数据结构再内容上高度类似(系统中的还要更为复杂)。

struct shmid_ds其中记录了该共享内存的属性,包括现在有哪些进程正在通过该共享内存通信的信息,以及key值等。

若想获取共享内存的属性参数,可以通过创建一个空的struct shmid_ds对象,再将地址传入shmctl函数中。注意此时的comd参数需传入IPC_STAT。

struct shmid_ds tmp;
shmctl(shmid,IPC_STAT,&tmp);

4.shmat函数和shmdt函数——对共享内存进行关联和去关联

注意:正确的释放共享内存的流程应该是,先将进程与共享内存去关联,然后再释放共享内存

这里附上笔者总结的共享内存创建流程:

在申请共享内存时应做到,谁申请,谁释放。

三、共享内存的优缺点分析

1.优点

共享内存在所有进程通信间,通信速度是最快的——能减少的拷贝次数。

何以见得共享内存能减少拷贝次数?

假如同样的代码和数据,综合考虑管道和共享内存分别进行通信,在考虑上键盘输入,和显示器输出后,共享内存有几次拷贝数据,管道呢?

由上图我们可以清楚的观察到,相比管道,共享内存不用在buffer缓冲区中临时中转一下,由此能够减少一定的数据拷贝。

2.缺点

共享内存在数据通信时,没有对数据做任何保护——没有同步、互斥机制。

甚至管道可能出现写端还未写完数据,而读端就来读取的情况——这时读端大概率读到无意义的数据。

比如,管道通信写端在没有写入数据时,读端会被OS阻塞,反之亦然;

管道在读端将数据读取后,写端再写会覆盖已读的数据。

是否能在不使用信号量的前提下,对共享内存进行保护?

可以给通信的进程双方添加管道,凡共享内存通信前先借助管道确认对方是否准备完毕。

读/写端先不直接访问共享内存,而是先通过管道通信确认后,再通过共享内存通信。

比如,读端想要通过共享内存读取数据之前,先在管道读端处读取信号(如一个特定字符)。若未读取到特定值字符,则由于管道的特性读端进程会被阻塞,直到写端发来信号。


总结

本文详细介绍了System V通信方式中的“共享内存”通信方式。从原理的介绍,到接口的使用,再到最后的优缺点分析,较为系统的剖析共享内存的原理和使用。

虽然共享内存在如今这个万物互联的世界越来越不常用,但在某些脱网单机情况下依旧是进程通信的最佳选择。

希望本文对你有所帮助。

读完点赞,手留余香~

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

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

相关文章

编程基础:执行流

能帮到你的话,就给个赞吧 😘 文章目录 执行流同步:顺序执行,只有一个执行流异步:新开后台(次)执行流,后台执行流要确保不能影响主执行流。共有两个执行流。 阻塞:任务阻塞执行流,导致…

理解非结构化文档:将 Reducto 解析与 Elasticsearch 结合使用

作者:来自 Elastic Adel Wu 演示如何将 Reducto 的文档处理与 Elasticsearch 集成以实现语义搜索。 Elasticsearch 与业界领先的生成式 AI 工具和提供商有原生集成。欢迎观看我们的网络研讨会,了解如何超越 RAG 基础,或使用 Elastic 向量数据…

[面试精选] 0094. 二叉树的中序遍历

文章目录 1. 题目链接2. 题目描述3. 题目示例4. 解题思路5. 题解代码6. 复杂度分析 1. 题目链接 94. 二叉树的中序遍历 - 力扣(LeetCode) 2. 题目描述 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 3. 题目示例 示例 1 : 输入&…

学习笔记(23): 机器学习之数据预处理Pandas和转换成张量格式[1]

学习笔记(23): 机器学习之数据预处理Pandas和转换成张量格式[1] 学习机器学习,需要学习如何预处理原始数据,这里用到pandas,将原始数据转换为张量格式的数据。 1、安装pandas pip install pandas 2、写入和读取数据 >>创建一个人工…

2025年6月6日第一轮

2025年6月6日 The rapid in Chiese industdy is developnig e,and it is From be in a enjoy a deep is developing The drone industry in China is developing The drone industy in china develops rapidly and is in a leading position in in the world. The dro…

12-Oracle 23ai Vector 使用ONNX模型生成向量嵌入

一、Oracle 23ai Vector Embeddings 核心概念​ 向量嵌入(Vector Embeddings)​​ -- 将非结构化数据(文本/图像)转换为数值向量 - - 捕获数据的语义含义而非原始内容 - 示例:"数据库" → [0.24, -0.78, 0.5…

pytorch 与 张量的处理

系列文章目录 文章目录 系列文章目录一、Tensor 的裁剪二、Tensor 的索引与数据筛选torch.wheretorch.indicestorch.gathertorch.masked_selecttorch.taketorch.nonzero(省略) 三、Tensor 的组合与拼接torch.cattorch.stack 四、Tensor的切片chunksplit …

layer norm和 rms norm 对比

Layer norm # Layer Norm 公式 mean x.mean(dim-1, keepdimTrue) var x.var(dim-1, keepdimTrue) output (x - mean) / sqrt(var eps) * gamma beta特点: 减去均值(去中心化)除以标准差(标准化)包含可学习参数 …

Java高级 | 【实验六】Springboot文件上传和下载

隶属文章:Java高级 | (二十二)Java常用类库-CSDN博客 系列文章:Java高级 | 【实验一】Springboot安装及测试 |最新-CSDN博客 Java高级 | 【实验二】Springboot 控制器类相关注解知识-CSDN博客 Java高级 | 【实验三】Springboot 静…

VBA进度条ProgressForm1

上一章《VBA如何使用ProgressBar进度条控件》介绍了ProgressBar控件的使用方法,今天我给大家介绍ProgressForm1进度条的使用方法,ProgressForm1是集成ProgressBar控件和Label控件的窗体,可以同时显示进度条和百分比,如下图&#x…

行为型设计模式之Interpreter(解释器)

行为型设计模式之Interpreter(解释器) 前言: 自己的话理解:自定义一个解释器用来校验参数或数据是否合法。 1)意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解…

深入解析 CAS 操作

一、CAS 的本质:硬件级别的乐观锁 CAS(Compare-And-Swap,比较并交换) 是一种原子操作指令,用于实现对共享变量的无锁并发修改。它是现代多核处理器支持的底层硬件指令,也是构建高效并发数据结构&#xff0…

vue3+TS+eslint9配置

记录eslint升级到9.x的版本之后遇到的坑 在 ESLint 9 中,配置方式发生了变化。Flat Config 格式(eslint.config.js 或 .ts)不再支持 extensions 选项。所以vscode编辑器中的 extensions 需要注释掉,要不然保存的时候不会格式化。…

【bug】Error: /undefinedfilename in (/tmp/ocrmypdf.io.9xfn1e3b/origin.pdf)

在使用ocrmypdf的时候,需要Ghostscript9.55及以上的版本,但是ubuntu自带为9.50 然后使用ocrmypdf报错了 sudo apt update sudo apt install ghostscript gs --version 9.50 #版本不够安装的版本为9.50不够,因此去官网https://ghostscript.c…

Redis :String类型

String类型 String是Redis中的字符串,是Redis中最基本的数据类型,直接是按照二进制数据的进行存储 Redis中的所有key都是String类型,但是value是有差别的 常见的命令 set 将String类型的value存储到key中,如果之间有相同的ke…

第18节 Node.js Web 模块

什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序。 Web服务器的基本功能就是提供Web信息浏览服务。它只需支持HTTP协议、HTML文档格式及URL,与客户端的网络浏览器配合。 大多数web服务器都支持服务…

网络爬虫一课一得

网页爬虫(Web Crawler)是一种自动化程序,通过模拟人类浏览行为,从互联网上抓取、解析和存储网页数据。其核心作用是高效获取并结构化网络信息,为后续分析和应用提供数据基础。以下是其详细作用和用途方向: …

LeetCode--24.两两交换链表中的结点

解题思路: 1.获取信息: 给了一个链表,要求两两一组地交换位置 限定条件:只能进行结点交换,不能修改结点内部的值 额外条件:结点数在0-100的范围,闭区间 2.分析题目:…

嵌入式SDK技术EasyRTC音视频实时通话助力即时通信社交/教育等多场景创新应用

一、引言​ 在数字化时代,即时通信已成为人们生活和工作中不可或缺的部分。音视频功能作为即时通信的核心,能实现更加直观、高效的信息传递。EasyRTC作为一款强大的实时通信框架,具备诸多优势,为即时通信的音视频应用提供了优质解…

IDEA集成JRebel插件,实现实时热部署

系列文章目录 文章目录 系列文章目录一、JRebel是什么?1.1、对比传统开发流程1.2、JRebel特性以及优势 二、IDEA集成JRebel三、IDEA以JRebel运行报错处理四、IDEA以JRebel运行演示实时热部署 一、JRebel是什么? JRebel 是一款针对 Java 开发的热部署工具…