Linux_进程间通信_共享内存
什么是共享内存?
对于两个进程,通过在内存开辟一块空间(操作系统开辟的),进程的虚拟地址通过页表映射到对应的共享内存空间中,进而实现通信;物理内存中的这块空间,就叫做共享内存。
共享内存的优缺点
优点:方便、接口简单、加快程序效率、不要求进程有“血缘”关系。
缺点:没有提供同步机制,需要借助其他手段进行进程间同步工作。
共享内存可以快于消息传递,但有高速缓存一致性问题。

shmget函数

功能:用来创建共享内存
参数:
- key_t key:一个键值,用于唯一标识一个共享内存段。由用户输入,不能由内核自主生成。若由内核生成,则会导致两个进程看不到同一块共享内存。你可以使用IPC_PRIVATE常量创建一个私有共享内存段,或使用ftok()函数根据文件路径生成一个唯一的键值。
- size_t size:共享内存的大小,以字节为单位。
- int shmflg:标志位,用于控制创建和获取共享内存的行为。
IPC_CREAT:若指定的共享内存不存在,创建并返回;若已存在,获取并返回。
即保证调用进程能拿到共享内存。
IPC_CREAT | IPC_EXCL:若共享内存不存在,创建并返回,若已存在,出错并返回。即只要成功,拿到的一定是新的共享内存(不拿旧的)!
- 返回值:成功时返回共享内存的标识符(一个非负整数),失败时返回-1。
// Comm代码模块
const std::string gpath = "/home/ubuntu/112/linux/lesson24-fifo";
int gprojId = 0x6666;
int gshmsize = 4096;
// Server代码模块
int main()
{// 1. 创建keykey_t k = ::ftok(gpath.c_str(), gprojId);if(k == -1){ perror("ftok errror: ");}std::cout << "k : " << ToHex(k) << std::endl;// 2.创建共享内存 && 获取int shmid = ::shmget(k, gshmsize, IPC_CREAT | IPC_EXCL);if(shmid < 0){std::cerr << "shmget error" << std::endl;return 2;}std::cout << "shmid: " << std::endl;return 0;
}

共享内存的管理指令(指令释放)
- ipcs :查询所有的system V通信方式

- ipcs -m :查询共享内存
这里的key值与上面查询的是一样的。
- ipcrm -m shmid:删除共享内存

删除共享内存之后,再运行server就成功了

shmid vs key
- shmid:只给用户用的一个标识shm的标识符
- key:只作为内核中,区分shm唯一性的标识符,不作为用户管理shm 的id值
共享内存的管理函数(代码释放)
shmctl函数

功能:用于控制共享内存原型
参数:
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向⼀个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

在上面代码的基础上,加上下面这句代码即可完成代码实现删除共享内存
shmctl(shmid, IPC_RMID, nullptr);
ftok函数
在shmget函数中我们说到参数key是唯一的且是由用户输入的,但是用户有没有可能设置的key有冲突呢?答案是肯定的。所以,基于这个问题,我们引入了ftok函数。你只要给我一个公共的路径和一个公共的项目ID,我就会依据算法生成一个唯一值。虽然这样也有可能造成冲突,但是冲突的几率特别特别小!
// Comm模块代码
const std::string gpath = "/home/ubuntu/112/linux/lesson24-fifo";
int projId = 0x6666;
// Client / Server模块代码
#include <iostream>
#include "Comm.hpp"
int main()
{key_t k = ::ftok(path.c_str(), projId);if(k < 0){std::cerr << "ftok error" << std::endl;return 1;}std::cout << "k: " << k << std::endl; return 0;
}

如果ftok函数返回失败时,我们就需要不断的尝试,对路径名和id值进行修改,直至成功。一般来说,有几种可能:
- 如果传入的路径名不存在
- 传入的路径名没有读取权限,无法读取该文件的索引节点号
- 文件的索引节点超过了8位,即超过了一个字节的范围
- 系统中已经使用了所有的IPC键值
shmat函数

功能:将共享内存段连接到进程地址空间原型(关联)
参数:
shmid:共享内存标识
shmaddr:指定连接的地址
shmflg:是一组按位OR(或)在一起的标志,用来控制读写权限等。它的两个可能取值是SHM_RND和SHM_RDONLY。若取值为SHM_RDONLY,则以只读方式连接此段,否则以读写的方式连接此段。
返回值:成功返回一个指向共享内存起始地址的指针;失败返回-1
说明:
- shmaddr为NULL,核心自动选择一个地址
- shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
- shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
- shmflg = SHM_RDONLY,表示连接操作用来只读共享内存
void* ret = shmat(shmid, nullptr, 0);// 将共享内存挂接到自己的地址空间中
注意:共享内存也有权限!
shmdt函数

功能:将共享内存段与当前进程脱离原型(去关联)
参数:
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
::shmdt(ret); // 去关联
shmdt的参数就是shmat的返回值。
共享内存的特点
优点
- 高效性:
- 共享内存是IPC通信中传输速度最快的通信方式。因为数据不需要在客户机和服务器之间拷贝,数据可以直接写到内存,避免了多次数据拷贝,从而大大提高了通信效率。
- 进程对共享内存的访问就如同访问自己的内存空间一样,不需要进行额外的系统调用或内核操作,进一步提升了效率。
- 灵活性:
- 允许多个进程共享数据,提供了一种灵活的通信方式。
- 进程间可以通过共享的内存区域进行双向通信,满足了多种通信需求。
- 支持大量数据传输:
- 适用于需要快速传递大量数据的场景,特别是在大数据处理、实时通信等领域表现突出。
缺点
- 具有同步相关的问题:
因为多个进程可以同时访问共享内存,因此需要额外的同步机制来避免 数据不一致性 问题。内核中并不提供任何对共享内存访问的同步机制,因此通常需要使用信号量等其他IPC机制进行读写同步与互斥。(例:写端要向共享内存中写入hello world,但只写了hello,读端就读走了)
- 安全性:
需要额外的安全机制来保护数据,防止其他进程非法访问。若未采取适当的安全措施,可能导致数据泄露或被篡改。
- 编程复杂性:
使用共享内存进行通信需要处理同步和数据一致性等复杂问题,编程复杂度较高。需要开发者具备深厚的操作系统和并发编程知识。
- 依赖操作系统支持:
共享内存的使用依赖于操作系统的支持。不同的操作系统或版本可能对共享内存的实现和管理方式存在差异,这增加了跨平台开发的难度。
相关文章:
Linux_进程间通信_共享内存
什么是共享内存? 对于两个进程,通过在内存开辟一块空间(操作系统开辟的),进程的虚拟地址通过页表映射到对应的共享内存空间中,进而实现通信;物理内存中的这块空间,就叫做共享内存。…...
ubuntu 下生成 core dump
在Ubuntu下,发现程序崩溃后不生成core dump文件, 即使设置了ulimit -c unlimited后仍然无效。 1.ulimit -c unlimited 输出的的含义是核心转储文件的大小限制,单位是blocks,默认是0,表示不生成core dump文件。 2. 重设core_pattern ulimit -c unlimited后,核心转储文件…...
学习HLS.js
前言 HTTP 实时流(也称为HLS(.m3u8))是一种基于HTTP的自适应比特率流通信协议。HLS.js依靠HTML5视频和MediaSource Extensions进行播放,其特点:视频点播和直播播放列表、碎片化的 MP4 容器、加密媒体扩展 …...
2025年华为OD上机考试真题(Java)——判断输入考勤信息能否获得出勤奖
题目: 公司用一个字符串来表示员工的出勤信息: absent:缺勤late:迟到leaveearly:早退present:正常上班 现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下&am…...
空对象模式
在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。 在空对象模式中,我…...
开启Excel导航仪,跨表跳转不迷路-Excel易用宝
都2025年了,汽车都有导航了,你的表格还没有导航仪吗?那也太OUT了。 面对着一个工作簿中有N多个工作表,工作表中又有超级表,数据透视表,图表等元素,如何快速的切换跳转到需要查看的数据呢&#…...
年度技术突破奖|中兴微电子引领汽车芯片新变革
随着以中央计算区域控制为代表的新一代整车电子架构逐步成为行业主流,车企在电动化与智能化之后,正迎来以架构创新为核心的新一轮技术竞争。中央计算SoC,作为支撑智驾和智舱高算力需求的核心组件,已成为汽车电子市场的重要新增量。…...
Ubuntu 如何查看盘是机械盘还是固态盘
在 Ubuntu 系统中,您可以通过以下方法来确定硬盘是机械硬盘(HDD)还是固态硬盘(SSD): 使用 lsblk 命令: 打开终端,输入以下命令: lsblk -d -o name,rota该命令将列出所…...
计算机网络(三)——局域网和广域网
一、局域网 特点:覆盖较小的地理范围;具有较低的时延和误码率;使用双绞线、同轴电缆、光纤传输,传输效率高;局域网内各节点之间采用以帧为单位的数据传输;支持单播、广播和多播(单播指点对点通信…...
STM32F4分别驱动SN65HVD230和TJA1050进行CAN通信
目录 一、CAN、SN65HVD230DR二、TJA10501、TJA1050 特性2、TJA1050 引脚说明 三、硬件设计1、接线说明2、TJA1050 模块3、SN65HVD230 模块 四、程序设计1、CAN_Init:CAN 外设初始化函数2、CAN_Send_Msg、CAN_Receive_Msg 五、功能展示1、接线图2、CAN 数据收发测试 …...
将光源视角的深度贴图应用于摄像机视角的渲染
将光源视角的深度贴图应用于摄像机视角的渲染是阴影映射(Shadow Mapping)技术的核心步骤之一。这个过程涉及到将摄像机视角下的片段坐标转换到光源视角下,并使用深度贴图来判断这些片段是否处于阴影中。 1. 生成光源视角的深度贴图 首先&…...
docker一键安装脚本(docker安装)
第一种方法一键安装命令 curl -O --url http://luyuanbo79.south.takin.cc/wenjian/docker_install.sh && chmod x docker_install.sh && ./docker_install.sh 备用方法 curl -O --url https://file.gitcode.com/4555247/releases/untagger_0896d4789937405…...
【SY2】Apollo10.0 Cyber基于Writer/Reader的通信方式
实验前提 Apollo10.0已经安装完毕Vscode及相关插件安装完成启动容器并进入在Vscode连接进入到Apollo工作空间下学习资料 部分配置如实验一https://blog.csdn.net/weixin_60062799/article/details/145029669?spm1001.2014.3001.5501 学习资料 Apollo7.0或其他版本可以参…...
【YOLOv8杂草作物目标检测】
YOLOv8杂草目标检测 算法介绍模型和数据集下载 算法介绍 YOLOv8在禾本科杂草目标检测方面有显著的应用和效果。以下是一些关键信息的总结: 农作物幼苗与杂草检测系统:基于YOLOv8深度学习框架,通过2822张图片训练了一个目标检测模型ÿ…...
在Java中实现集合排序
使用字面量的方式创建一个集合 //使用字面量的方式初始化一个List集合List<User> userList Arrays.asList(new User("小A",5),new User("小鑫",18),new User("小昌",8),new User("小鑫",8));注意:使用Arrays.asLis…...
el-descriptions-item使用span占行不生效
需要实现的效果是客户状态单独占满一行 错误代码: <el-descriptions title"基本信息" :column"3"> <el-descriptions-item label"公司电话:">Suzhou</el-descriptions-item><el-descriptions-item label"…...
Android 绘制学习总结
1、刷新率介绍 我们先来理一下基本的概念: 1、60 fps 的意思是说,画面每秒更新 60 次 2、这 60 次更新,是要均匀更新的,不是说一会快,一会慢,那样视觉上也会觉得不流畅 3、每秒 60 次,也就是 1…...
Linux下部署SSM项目
作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 Linux部署SSM项目 打包项目 1、修改pom.xml文件,打包方式改为war <packaging>war</packaging>2、idea 通过maven的clean,…...
计算机网络 笔记 数据链路层 2
1,信道划分: (1)时分复用TDM 将时间等分为“TDM帧”,每个TDM帧内部等分为m个时隙,m个用户对应m个时隙 缺点:每个节点只分到了总带宽的1/m,如果有部分的1节点不发出数据,那么就会在这个时间信道被闲置,利用…...
xml简介
目录 基本语法特点及应用场景一个简单示例 xml(全称eXtensible Markup Language)是一种用于存储和传输数据的标记语言,跨平台并且跨语言,xml内容较多,这篇文章会介绍一些基础的内容。 基本语法 xml文档通常以xml声明开…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
