共享内存与存储映射(mmap)
【前言】对这两个理解还是不够深刻,写一篇博客来记录一下。
首先关于共享内存的链接:共享内存。里面包含了创建共享内存区域的函数,以及两个进程怎么挂载共享内存通信,分离、释放共享内存。
共享内存的好处就是效率高,不需要太多次的进行数据的copy。可以直接进行读写内存。所以,相对来说在IPC进程间通信三大主题里面,共享内存要比消息队列使用多,而且消息队列只在有血缘关系的进程间通信;但是,共享内存不保证同步,使用了信号量用来保证共享内存同步。Linux中的两种共享内存。一种是我们的IPC通信System V版本的共享内存,另外的一种就是我们今天提到的存储映射I/O(mmap函数),当然还有一种POSIX的共享内存,它是在mmap基础之上构建的。
一、mmap
mmap I/O的描述符间接说明内存映射是对文件操作。另外,mmap另外可以在无亲缘的进程之间提供共享内存区。这样,类似的两个进程之间就是可以进行了通信。
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上,运行着进程), 通过对这段内存的读取和修改, 实现对文件的读取和修改。mmap()系统调用使得进程之间可以通过映射一个普通的文件实现共享内存。普通文件映射到进程地址空间后,进程可以像访问内存的方式对文件进行访问,不需要其他内核态的系统调用(read,write)去操作。
这里是讲设备或者硬盘存储的一块空间映射到物理内存,然后操作这块物理内存就是在操作实际的硬盘空间,不需要经过内核态传递。比如你的硬盘上有一个文件,你可以使用linux系统提供的mmap接口,将这个文件映射到进程一块虚拟地址空间,这块空间会对应一块物理内存,当你读写这块物理空间的时候,就是在读取实际的磁盘文件,就是这么直接高效。通常诸如共享库的加载都是通过内存映射的方式加载到物理内存的。
mmap系统调用并不完全是为了共享内存来设计的,它本身提供了不同于一般对普通文件的访问的方式,进程可以像读写内存一样对普通文件进行操作,IPC的共享内存是纯粹为了共享。
(1)mmap系统调用介绍:
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
这就是mmap系统调用的接口,mmap函数成功返回指向内存区域的指针,失败返回MAP_FAILED。
addr,某个特定的地址作为起始地址,当被设置为NULL,标识系统自动分配地址。实实在在的物理区域。
length说的是内存段的长度。
prot是用来设定内存段的访问权限。
| prot参数 | 说明 |
|---|---|
| PROT_READ | 内存段可读 |
| PROT_WRITE | 内存段可写 |
| PROT_EXEC | 内存段可执行 |
| PROT_NONE | 内存段不能被访问 |
flags参数控制内存段内容被修改以后程序的行为。
| flags参数 | 说明 |
|---|---|
| MAP_SHARED | 进程间共享内存,对该内存段修改反映到映射文件中。提供了POSIX共享内存 |
| MAP_PRIVATE | 内存段为调用进程所私有。对该内存段的修改不会反映到映射文件 |
| MAP_ANNOYMOUS | 这段内存不是从文件映射而来的。内容被初始化为全0 |
| MAP_FIXED | 内存段必须位于start参数指定的地址处,start必须是页大小的整数倍(4K整数倍) |
| MAP_HUGETLB | 按照大内存页面来分配内存空间 |
fd参数是用来被映射文件对应的文件描述符。通过open系统调用得到。
offset设定从何处进行映射。
(2)mmap用于共享内存的方式
1、我们可以使用普通文件进行提供内存映射,例如,open系统调用打开一个文件,然后进行mmap操作,得到共享内存,这种方式适用于任何进程之间。
2、可以使用特殊文件进行匿名内存映射,这个相对的是具有血缘关系的进程之间,当父进程调用mmap,然后进行fork,这样父进程创建的子进程会继承父进程匿名映射后的地址空间,这样,父子进程之间就可以进行通信了。相当于是mmap的返回地址此时是父子进程同时来维护。
3、另外POSIX版本的共享内存底层也是使用了mmap。所以,共享内存在在posix上一定程度上就是指的内存映射了。https://www.cnblogs.com/LubinLew/p/POSIX-shared_memory.html
三、mmap和System V共享内存的比较
共享内存:
这是System V版本的共享内存(以下我们统称为shm),下面看下mmap的:
总结:
1、mmap是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射。而shm共享内存,每个进程最终会映射到同一块物理内存。shm保存在物理内存,这样读写的速度肯定要比磁盘要快,但是存储量不是特别大。
2、相对于shm来说,mmap更加简单,调用更加方便,所以这也是大家都喜欢用的原因。
3、另外mmap有一个好处是当机器重启,因为mmap把文件保存在磁盘上,这个文件还保存了操作系统同步的映像,所以mmap不会丢失,但是shmget在内存里面就会丢失。
4、总之,共享内存是在内存中创建空间,每个进程映射到此处。内存映射是创建一个文件,并且映射到每个进程开辟的空间中。
但在posix中的共享内存就是指这种使用文件的方式“内存映射”。参考:https://www.cnblogs.com/LubinLew/p/POSIX-shared_memory.html
附录:linux高端内存https://www.cnblogs.com/wuchanming/p/4360277.html
共享内存与存储映射(mmap)的更多相关文章
- 使用PHP在共享内存中存储数据集
我们可以使用共享内存作为一种独特的存储选项,提供快速读/写操作和进程互操作性等优势. 对于 Web 应用程序,这意味着: 缓存存储(数据库查询.Web 服务数据.外部数据) 会话存储 应用程序之间的数 ...
- 存储映射--mmap
存储映射 使一个磁盘文件与存储空间中的一个缓冲区相映射. 当从缓冲区中取数据,就相当于读文件中的相应字节. 将数据存入缓冲区,则相应的字节就自动写入文件. 使用这种方法,首先应通知内核,将一个指定文件 ...
- mmap映射区和shm共享内存的区别总结
[转载]原文链接:https://blog.csdn.net/hj605635529/article/details/73163513 linux中的两种共享内存.一种是我们的IPC通信System ...
- mmap映射文件至内存( 实现 共享内存 与 文件的另类访问 )
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: < ...
- Linux内存映射--mmap函数
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: < ...
- UNIX环境高级编程——存储映射I/O(mmap函数)
共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共 ...
- Linux IPC实践(8) --共享内存/内存映射
概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS ...
- linux下共享内存mmap和DMA(直接访问内存)的使用 【转】
转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...
- Linux下多任务间通信和同步-mmap共享内存
Linux下多任务间通信和同步-mmap共享内存 嵌入式开发交流群280352802,欢迎加入! 1.简介 共享内存可以说是最有用的进程间通信方式.两个不用的进程共享内存的意思是:同一块物理内存被映射 ...
随机推荐
- WPF 之 依赖属性与附加属性(五)
一.CLR 属性 程序的本质是"数据+算法",或者说用算法来处理数据以期得到输出结果.在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法). ...
- Broken robot CodeForces - 24D (三对角矩阵简化高斯消元+概率dp)
题意: 有一个N行M列的矩阵,机器人最初位于第i行和第j列.然后,机器人可以在每一步都转到另一个单元.目的是转到最底部(第N个)行.机器人可以停留在当前单元格处,向左移动,向右移动或移动到当前位置下方 ...
- Codeforces Round #672 (Div. 2) D. Rescue Nibel! (思维,组合数)
题意:给你\(n\)个区间,从这\(n\)区间中选\(k\)个区间出来,要求这\(k\)个区间都要相交.问共有多少种情况. 题解:如果\(k\)个区间都要相交,最左边的区间和最右边的区间必须要相交,即 ...
- Codeforces Round #481 (Div. 3) D. Almost Arithmetic Progression (暴力)
题意:有一个长度为\(n\)的序列,可以对所有元素++或--,求最少的操作次数,如果无论如何都不能构成,则输出\(-1\). 题解:一个等差数列一定由首项\(a_{1}\)和公差\(d\)来决定,而这 ...
- C# 类 (10) - 命名空间NameSpace
NameSpace 命名空间是一系列 类型的集合,比如很多方法,很多类,集合在一个空间(myspace)里,谁想用就先 using myspace,然后直接用不using myspace的话,想用里面 ...
- IOS键盘收起后,页面底部留白处理
环境:vue+vant 的H5页面 场景:输入框输入信息时,如登录.注册等表单信息 问题:键盘收回后页面底部留白,导致dialog组件按钮位移,视觉上,其中的按钮无法正常工作 解决方案:监听失去焦点时 ...
- 洛谷p1637 三元上升子序列(树状数组
题目描述 Erwin最近对一种叫"thair"的东西巨感兴趣... 在含有n个整数的序列a1,a2......an中, 三个数被称作"thair"当且仅当i&l ...
- AirPods Max 出厂激活是怎么回事
AirPods Max 出厂激活是怎么回事 话说出厂激活是怎么检测出来的 refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问! 原创文 ...
- css scroll text without wrap & webkit-scrollbar
css scroll text without wrap hidden webkit-scrollbar .tabs-title-box::-webkit-scrollbar, .tabs-conte ...
- VS Code Extension
VS Code Extension https://code.visualstudio.com/api/get-started/your-first-extension xgqfrms 2012-20 ...