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声明开…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
