共享内存

C++进程间通信之共享内存 C++共享内存是一种用于多进程或多线程之间进行数据交换的机制。它允许不同的进程或线程在同一块内存空间中共享数据,从而实现高效的通信和协作。共享内存在数据密集型应用程序中具有重要的作用和价值。共享内存的主要作用之一是提高程序的性能和效率。由于共享内存是直接访问内存中的数据,而不需要复制或传输数据,因此可以避免不必要的数据拷贝和通信开销。这样,在多个进程或线程之间进行数据共享和交换时,共享内存可以大大减少时间和资源消耗,提高应用程序的运行效率。共享内存还具有提供更方便的数据共享和同步机制的重要性。 阅读详情

    共享内存是IPC形式中最快的方式。一旦将这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核。然而往该共享内存区存放信息或从中取走信息的进程间通常需要某种方式的同步。

    实现共享内存的方式:利用mmap函数、使用Posix共享内存区、使用SystemV共享内存区,下面分别介绍。

1.1 利用mmap进行内存映射

    作用:open文件之后调用mmap把它映射到调用进程地址空间的某个文件。之后所有的I/O都在内核的掩盖下完成,只需编写存取映射区中各个值的代码即可,而不必调用read、write或lseek进行操作。

    需要说明的一点:并不是所有文件都能进行内存映射,如终端和套接字的描述符不支持内存映射,试图将其映射到内存将导致mmap返回一个错误。这些类型的描述符必须使用read和write(或者相关变体)来访问。

    相关函数:mmap,mumap(删除共享内存)及msync(用于同步共享内存和文件的内容),下面仅介绍mmap。

void *mmap(void *addr, size_t len, intprot, inf flag, off_t offset);

返回值:成功返回被映射区的起始地址,失败返回MAP_FAILED

参数说明:

         addr指定描述符fd应被映射到的进程内空间的起始地址,为了保证可移植性,通常被指定为一个空指针,这样就有内核自行选择起始地址。

         len参数为映射到进程地址空间中的 字节数,它从被映射文件开头的offset个字节处开始算。

         prot参数指定了映射内存的读、写、执行等相关权限,取值可为PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE(不可访问)

         flag指示该共享内存的作用效果,通常取为MAP_SHARED(变量是共享的,调用进程对被映射数据所作的修改对于共享该对象的所有进程可见,并改变了底层支持对象——通常是文件);如果指定为MAP_PRIVATE,那么调用进程对被映射数据所做的修改只对该进程可见,同时也不改变底层支持对象;以上两个标志必须指定一个,当需要准确解释addr指向的地址参数时或上MAP_FIXED。

    作用:分别用于把一个文件或一个Posix共享内存区对象映射到调用进程的地址空间,有三种目的:

1)      使用普通文件以提供内存映射I/O(应用最广泛)

2)      使用特殊文件以提供匿名内存映射  

有两种方法:

4.4BSD提供匿名内存映射,避免了文件的创建和打开。其通过把mmap的flag参数指定成MAP_SHARED|MAP_ANON,把fd参数指定为-1.忽略offset参数。这样的内存区被初始化为0。(由fork或具有亲缘关系的线程使用)

SVR4提供了/dev/zero设备文件,open它之后可以使用得到的文件描述符,然后里面mmap进行内存映射,之后执行关闭即可。这样的映射保证内存映射区被初始化为0(可由无亲缘关系的进程使用)

3)      使用shm_open以提供无亲缘关系进程间的Posix共享内存区

 

    访问共享内存时,文件大小和内存映射大小可以不同,下面进行访问情况的两点说明:

a)        文件大小等于内存映射区的大小:只能访问相应大小的共享内存,超出的话会引发SIGSEGV信号

b)        文件大小小于共享内存区的大小:只能访问文件大小+最后一页上该对象以远的那些字节,访问超过的内存(超过文件大小但小于共享内存大小)时,会引发SIGBUS信号。若想访问这部分内存,需要增加文件大小,可用lseek或者ftruncate函数调整文件大小。

1.2 POSIX共享内存

         Posix共享内存是由shm_open打开一个Posix IPC名字(也许是在文件系统中的一个文件),所返回的描述符由mmap函数映射到当前进程的地址空间。即涉及以下步骤:

1、  指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开一个已存在的共享内存区对象

2、  调用mmap把这个共享内存区映射到调用进程的地址空间

相关函数:

头文件:#include <sys/mman.h>

创建或打开共享内存区对象:

int shm_open(const char *name, into flag,mode_t mode)  //成功返回非负描述符,若出错则为-1,name为绝对路径的Posix IPC名字形式

删除共享内存区对象:

int shm_unlink(const char *name)   //成功返回0,失败-1

p.s:当调用mmap完成内存映射之后就可以关闭描述符了,因为已经得到共享内存区的指针了;之后的操作同mmap。与mmap映射文件实现共享内存基本类似,不同的是获取文件描述符的方式。

1.3 System V共享内存

         SystemV共享内存区在概念上类似与Posix共享内存区。其获取共享内存区的方式为先调用shmget,再调用shmat,对于每个共享内存区,内存维护一个shmid_ds对象

相关函数:

头文件 #include <sys/shm.h>

1)      创建或打开:

int shmget(key_t key, size_t size, intoflag)   //若成功则为共享内存区对象,若出错则为-1;其中key可以是ftok函数的返回值,也可以是IPC_PRIVATE;size指示了共享内存区的大小(以字节为单位),当实际操作为访问一个已存在的共享内存区时,应该为0,而创建时则应大于0

p.s:shmget并没有给调用进程提供访问该内存区的手段,故需要调用shmat

2)      附加共享内存区到调用进程的地址空间:

void *shmat(int shmid, const void *shmaddr,int flag); //若成功则返回映射区的起始地址,若出错则为-1;shmaddr一般取为0,这样系统会替调用者选择地址,这是推荐的的方法(可移植性好),若不为0的话则附加由shmaddr参数指定的地址,这时还和flag参数有关

断开共享内存(当使用完后调用):

int shmdt(const void * shmaddr);    //成功返回0,失败返回-1

p.s:当进程终止时,它当前附接着的所有共享内存区都自动断接掉。函数并不会删除共享内存,执行删除的话需要以参数为IPC_RMID调用shmdt

3)      控制操作:

int shmctl(int shmid, int cmd, structshmid_ds * buff); //若成功返回0,若出错为-1

当cmd取不同值时,函数可以实现三个功能如下:

IPC_RMID:从系统中删除指定的共享内存,这时buff参数置空

IPC_SET:给所指定的共享内存区设置其shmid_ds结构的以下三个成员:shm_perm.uid,shm_perm.did及shm_perm.mode,它们的值来自buff参数的相应成员。shm_ctime的值也用当前时间替换。

IPC_STAT:获取所指定共享内存当前的shmid_ds结构

 

与System V消息对了和System V信号量一样,System V共享内存区也存在特定的系统限制。可以在共享内存相关manual 文件中查看,如man shmget


C++ IPC进程间的通信《C++多线程编程实战》 临界值:程序中能被访问共享内存的部分 进程间通信示例:程序一开始就有2个进程,它们在一个普通窗口中完成绘制矩形的任务。2个进程相互通信,一个进程再画矩形时,另一个进程要等待 IPCWorker.cpp #include &amp;amp;lt;Windows.h&amp;amp;gt; #include &amp;amp;lt;tchar.h&amp;amp;gt; //_tcscmp() _TCHAR* #define COMMUNI 阅读详情

相关推荐

共享内存的用法

Linux进程间通信(六):共享内存 shmget()、shmat()、shmdt()、shmctl() 下面将讲解进程间通信的另一种方式,使用共享内存。 一、什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc()分配的内存一样。而如果某个

weixin_48268119的博客 2075

共享内存 C++

共享内存是一种进程间通信的方式,它允许多个进程访问同一个物理内存区域,从而可以实现数据的共享。在共享内存机制中,创建并维护一个共享内存区域的进程被称为共享内存的拥有者。其他进程可以通过映射该共享内存区域到自己的地址空间中来访问共享内存中的数据,从而实现进程间的通信和数据共享。易于使用:共享内存是一个非常通用的通信机制,因为它可以使用标准的共享内存API在不同的操作系统和编程语言中实现。灵活性:共享内存可用于实现不同类型的进程间通信,包括线程间通信和不同计算机之间的通信。

qq_41553944的博客 1696

【并发编程五】c++进程通信——共享内存(shared memmory)

现代操作系统,对于内存管理,采⽤的是虚拟内存技术,也就是每个进程都有⾃⼰独⽴的虚拟内存空间,不同进程的虚拟内存映射到不同的物理内存中。所以,即使进程 A中 和 进程 B中 的虚拟地址是⼀样的,其实访问的是不同的物理内存地址,对于数据的增删查改互不影响。这样这个进程写⼊的东⻄,另外⼀个进程⻢上就能看到了,都不需要拷⻉来拷⻉去,传来传去,⼤⼤提⾼了进程间通信的速度。⽤了共享内存通信⽅式,带来新的问题,那就是如果多个进程同时修改同⼀个共享内存,很有可能就冲突了。那共享内存的⽅式,就很好的解决了这⼀问题。

junxuezheng的博客 1万+

C++ 创建共享内存

共享内存用于实现进程间大量的数据传输,共享内存是在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问时间等。返回值:(1)成功,返回共享内存标识符(2)出错,返回-1,错误原因存于errno中。shmflag: 指定共享内存的访问权限和映射条件,一般设置为0,即读写权限。返回值:成功:0,出错:-1,错误原因存在于errno中。返回值:成功:0,出错:-1,错误原因存在于errno中。参数:shmaddr:指定共享内存的映射地址。作用:共享内存的内存管理。

hanxiaoyong_的博客 3254

Python 驱动 CAD 二次开发:从零搭建自动化绘图环境

本文详细介绍了如何利用Python进行CAD二次开发,实现自动化绘图。通过win32com库建立Python与CAD软件的通信,文章从环境搭建、连接CAD、操作文档到核心绘图与批量处理,提供了完整的实战指南。该方法能显著提升机械设计、建筑绘图等领域的重复性工作效率,将创造力从繁琐劳动中解放出来。

weixin_29093169的博客 1228

caxa二次开发实例展示

本人有8年CAXA各产品(如电子图版、工艺图表、PDM等)二次开发经验,参与过国家电网南瑞集团、中石油、龙记集团、欧姆龙集团、港日集团、中集集团、中国五矿、方圆塑机、大连锅炉、金蝶PDM集成CAXA,TEAMCENTER集成CAXA、大连锅炉机械、中国中车等项目的开发,擅长CAXA电子图版、CAXA工艺图表的二次开发,有需要的可以联系我,电话:13169467685、13249738576 Q

hourui800720的专栏 8028

初识Linux · 共享内存

size代表的是开辟的共享内存的大小,对于shmflg,也就是共享内存的标志,我们这里就介绍两个常用的,一个是IPC_CREAT 一个是IPC_EXCL,使用时候我们可以分为IPC_CREAT使用,IPC_EXCL单独使用没有意义,IPC_CREAT | IPC_EXCL使用。其中key是16进程的,所以我们前面会转成16进程的方便观察,shmid是0,owner是lazy,perms权限为0,共享内存的大小是4096,nattch对应的是0,代表的意思是挂接的进程为0,status状态。

更新各种计算机技能~ 1606

华为海思2026届数字IC秋招笔试高频考点解析与实战技巧(2025最新版)

本文深入解析华为海思2026届数字IC秋招笔试的高频考点与实战技巧,涵盖时序优化、低功耗设计、DFT规则等核心模块。针对2025年最新真题,提供详细的解题思路和工程经验,帮助考生高效备考。特别关注SystemVerilog约束随机测试等新增考点,助力考生在秋招笔试中脱颖而出。

m2n3o4p5的博客 414

共享内存C++

共享内存是两个或多个进程共享的内存。 但是,为什么我们需要共享内存或其他通信方式呢? 重申一下,每个进程都有自己的地址空间,如果任何进程想要将自己的地址空间的某些信息与其他进程进行通信,那么只能通过IPC(进程间通信)技术进行。 我们已经知道,通信可以在相关或不相关的进程之间进行。 通常,使用管道或命名管道来执行相互关联的进程通信。 可以使用命名管道或通过共享内存和消息队列的常用IPC技术执行无关的进程(例如在一个终端中运行一个进程而在另一个终端中运行另一个进程)通信。 我们已经看到了管道和命名管道的

Young_Bobooo的博客 9497

安卓无障碍服务保活实战:如何用AccessibilityService实现后台常驻(附完整代码)

本文深入解析如何利用Android无障碍服务(AccessibilityService)实现后台服务保活,涵盖多版本系统适配、前台服务集成、开机自启机制等关键技术。通过详细的Kotlin代码示例和合规性指导,帮助开发者构建稳定可靠的后台服务解决方案,同时避免因滥用无障碍服务导致的应用下架风险。

milk5的博客 1072

地瓜机器人RDK Studio使用入门教程

不知道大家在使用AI开发板的时候有没有遇到过板子官方镜像占据空间大难以保存,想要的时候找不到?官方示例项目久而久之便难以找寻?首次登陆开发板连接网络还需要准备显示器键盘鼠标外设繁杂?…为了解决平时开发过程中遇到的种种不便利问题,地瓜机器人创新的推出了RDK Studio这一官方开发者软件,使智能机器人开发迎来新纪元!通过这一软件极大降低了机器人的开发门槛,哪怕是零基础的用户亦可轻松上手RDK系列板卡!

xiongqi123123的博客 3427

C++共享内存

共享内存 注意:急着直接使用的直接到最后一个地方复制我封装的类,简单看一下前面的说明,直接用就行了 开始正文吧 首先用我自己的理解介绍共享内存是什么:共享内存就是在当前进程上 连接或开辟 一块内存空间。连接表示的意思是共享空间已经存在,被其它进程开辟过了,两个或多个进程都可以访问共享空间达到了进程间通信的目的 我们在linux下可以使用: ipcs -m 查看当前系统的共享内存 ipcrm -m shmid(ipcs -m 查看) 删除共享内存 创建共享内存 #include <sys/ipc.h

qq_44113911的博客 4224

华为OD机考双机位C卷 - 打印机队列 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 打印机队列

算法大师! 4619

Linux 共享内存

我们之前提到过,进程通信是让两个不同的进程看到同一份资源,所以我们给大家讲解了匿名管道和命名管道。今天我们还有一种方式两个不同的进程看到同一份资源。那就是共享内存!二、共享内存原理我们先来看这张图,我们在物理内存创建一个共享区,我们再让两个不同的进程通过页表分别映射到对应的共享区里,然后返回虚拟地址的起始地址。这就是共享内存,我们总结分为三步申请内存。将该内存挂接到进程地址空间的共享区。返回虚拟地址首地址。以上我们就创建好共享内存了,那我们该如何释放共享内存呢?

puppy_1mo的博客 1357

【毕设全程指导】基于YOLOv8的包装商品检测与可视化系统(SKU110K实战)

本文介绍了一个基于YOLOv8的包装商品检测与可视化系统毕业设计方案。项目采用SKU110K数据集,通过CSV转TXT格式转换适配YOLO模型训练,包含详细的环境搭建、模型配置和训练流程。系统实现了包装商品的自动化检测,并开发了Tkinter可视化界面进行交互式检测展示。该方案结合产业应用需求与技术深度,既具备实用价值,又能充分展示学生的技术能力,适合作为计算机视觉相关专业的毕业设计选题。整个项目从数据准备到界面开发完整覆盖,帮助学生系统掌握目标检测项目的完整实现流程。

LXY_LOVE36的博客 145

【2026年阿里巴巴集团暑期实习- 4月25日-算法岗-第二题- 矩阵计数】(题目+思路+Java&C++&Python解析+在线测试)

摘要: 给定两个非负整数序列a和b,构造n×m矩阵C,其中C[i][j]=a[i]×b[j]。统计矩阵中元素≥k的数量。解法是先对数组b排序,然后对于每个a[i],若k=0则直接累加m;若a[i]=0且k>0则跳过;否则计算需要的最小b[j]值,在排序后的b中使用二分查找确定满足条件的元素数量。时间复杂度为O((n+m)log m),空间复杂度O(1)。代码实现了排序和二分查找的高效组合。

m0_73659489的博客 65

共享内存实现

代码执行完,进程结束,再次执行时就会报错,文件已经存在,是因为进程结束时,共享内存的资源并没有释放掉,它的生命周期是随内核的,需要手动删除文件释放资源。对于删除操作,在用用户层不能使用key来指定删除,需要用到shmid进行资源管理。

2302_80378107的博客 1282

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Python的共享内存、共享内存队列

pythons通过共享内存、共享内存队列进行图像传输、提升性能的示例

WonderThink的博客 3074

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【共享内存】

多个进程能把同一段共享内存段“连接到”它们自己的地址空间里去,一个进程向共享内存写入数据,所做的改动会即时被访问同一段共享内存的其他进程看到。共享内存本身不提供进程间的同步机制,因此在多进程访问时,通常需要结合信号量、互斥锁等机制,来确保数据的正确读写。由于多个CPU需要快速访问存储器,就要对存储器进行缓存(Cache),任何一个缓存的数据被更新后,共享内存需要立即更新,以确保不同的处理器使用相同的数据。在多处理器的计算机系统中,它是可被不同中央处理器(CPU)访问的大容量内存。

xx 1325

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

共享内存(共享内存的映射,用共享内存读写,共享内存的控制)

共享内存允许两个或者多个进程共享给定的存储区域。共享内存的特点1、 共享内存是进程间共享数据的一种最快的方法。一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到 其中的内容。2、使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去 读、写这些数据。共享内存示意图总结。

BEIFEN13的博客 2001

共享内存及其用mmap实现共享内存

一、什么是共享内存顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访

Comedly的博客 6489

Linux——共享内存

这样的内存区域被所有共享它的进程所拥有,进程可以将数据写入共享内存区域,也可以从中读取数据。3. shmflg: 用于指定创建共享内存段的访问权限和其他标志,比如权限位和内存段的创建方式等。1. key: 用于标识共享内存段的键值,不同的进程使用相同的 key 值可以获取到同一个共享内存。用于将共享内存段附加到调用进程的地址空间,并返回一个指向共享内存段起始地址的指针。结构体的指针,用于存储或传递共享内存段的状态信息或权限设置。函数的返回值是一个指针,指向共享内存段的起始地址。

m0_74774362的博客 1447

【Linux】共享内存

本文详细介绍了共享内存的概念、实现方式及其在进程间通信中的应用。共享内存通过系统调用shmget创建,并使用shmat将其映射到进程的虚拟地址空间,从而实现多个进程访问同一块物理内存。文章还探讨了共享内存的管理指令(如ipcs和ipcrm)以及相关函数(如shmctl和shmdt)的使用方法。共享内存的优点是通信速度快,但缺乏保护机制,需通过信号量等方式进行同步。最后,文章通过代码示例展示了如何在客户端和服务器端使用共享内存进行通信,并提供了Makefile和头文件的实现细节。

C/C++、数据结构、Linux.... 986
上一篇: 常用的一些shell变量
下一篇: svn 常用命令
LinuxG_G
博客等级 码龄15年 58粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值