文件内存映射mmap解决大文件快速读写问题和进程间共享内存
mmap函数主要用途有三个:
1、将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能;
2、将特殊文件进行匿名内存映射,可以为关联进程提供共享内存空间;
3、为无关联的进程提供共享内存空间,一般也是将一个普通文件映射到内存中。
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改。
一、使用步骤
* 用open系统调用打开文件, 并返回描述符fd.
* 用mmap建立内存映射, 并返回映射首地址指针start.
* 对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).
* 用munmap(void *start, size_t lenght)关闭内存映射.
* 用close系统调用关闭文件fd.
二、mmap函数用法
* 头文件:
#include <unistd.h>
#include <sys/mman.h>
* 函数:void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize);
参数start:指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。
参数length:代表将文件中多大的部分映射到内存。
参数prot:映射区域的保护方式。可以为以下几种方式的组合:
PROT_EXEC 映射区域可被执行
PROT_READ 映射区域可被读取
PROT_WRITE 映射区域可被写入
PROT_NONE 映射区域不能存取
参数flags:影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
MAP_SHARED对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。
MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享(我感觉是可以的吧,不然怎样实现的父子进程间通信)。
MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。
参数fd:要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。
参数offset:文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。
返回值:
若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。
错误代码:
EBADF 参数fd 不是有效的文件描述词
EACCES 存取权限有误。如果是MAP_PRIVATE 情况下文件必须可读,使用MAP_SHARED则要有PROT_WRITE以及该文件要能写入。
EINVAL 参数start、length 或offset有一个不合法。
EAGAIN 文件被锁住,或是有太多内存被锁住。
ENOMEM 内存不足。
* 系统调用mmap()用于共享内存的两种方式:
(1)使用普通文件提供的内存映射:
适用于任何进程之间。此时,需要打开或创建一个文件,然后再调用mmap()
典型调用代码如下:
fd=open(name, flag, mode); if(fd<0) ...
ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0);
通过mmap()实现共享内存的通信方式有许多特点和要注意的地方,可以参看UNIX网络编程第二卷。
(2)使用特殊文件提供匿名内存映射:
适用于具有亲缘关系的进程之间。由于父子进程特殊的亲缘关系,在父进程中先调用mmap(),然后调用 fork()。那么在调用fork()之后,子进程继承父进程匿名映射后的地址空间,同样也继承mmap()返回的地址,这样,父子进程就可以通过映射区域进行通信了。注意,这里不是一般的继承关系。一般来说,子进程单独维护从父进程继承下来的一些变量。而mmap()返回的地址,却由父子进程共同维护。对于具有亲缘关系的进程实现共享内存最好的方式应该是采用匿名内存映射的方式。此时,不必指定具体的文件,只要设置相应的标志即可。
文件内存映射mmap解决大文件快速读写问题和进程间共享内存相关推荐
- linux共享内存示例,linux 进程间共享内存示例
写入端: #include #include #include #include #include using namespace std; struct MappingDataType { int ...
- 安卓执法仪录像之进程间共享内存
背景 之前我在文章里说过,我们的录像模块是跨进程的.为什么要这样设计,是因为录像这个过程是一个长期执行的过程,中间不能有断开.为了保证稳定性,通过进程隔离将录像业务同主业务分离. 通常情况下,如果在录 ...
- 进程间共享内存(信号量实现同步)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yongjiuzhizhen.blog.51cto.com/7980250/132 ...
- iOS之深入解析文件内存映射MMAP
一.常规文件操作 常规文件操作(read/write)有以下重要步骤: 进程发起读文件请求: 内核通过查找进程文件符表,定位到内核已打开文件集上的文件信息,从而找到此文件的 inode: inode ...
- c++ 内存映射文件进程间共享数据
int main(int argc, char *argv[]) { //RecursiveDelete("C:\\20_128\\"); //Self ...
- Java 中的内存映射Mmap
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 mmap 前言 一.mmap基础概念? 二.mmap 内存映射原理 (一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域 ...
- linux mmap 内存映射 mmap() vs read()/write()/lseek()
From: http://www.perfgeeks.com/?p=723 通过strace统计系统调用的时候,经常可以看到mmap()与mmap2().系统调用mmap()可以将某文件映射至内存(进 ...
- linux进程间通信快速入门【二】:共享内存编程(mmap、XSI、POSIX)
文章目录 mmap内存共享映射 XSI共享内存 POSIX共享内存 参考 使用文件或管道进行进程间通信会有很多局限性,比如效率问题以及数据处理使用文件描述符而不如内存地址访问方便,于是多个进程以共享内 ...
- Linux下进程通信---共享内存之:shm
进程通信:进程与进程间的数据交换,称为进程通信.进程通讯的方式有:共享内存.信号量.管道.消息队列.socket等等. 共享内存:内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内 ...
最新文章
- Java HashMap涉及的数据结构及实现
- php 时间倒计时代码 个人写法 有好的想法的欢迎贴出来分享
- POJ2391 Floyd+离散化+二分+DINIC
- 基于.net的分布式系统限流组件
- python编译器如何设置中文_如何使setup.py test使用特定的fortran编译器?
- 2012年12月第三个周末
- Apache ActiveMQ教程
- waf 防火墙限制_Web攻击分类有哪些?防火墙WAF可以抵御哪些攻击?
- C++打印size_t和ssize_t和int64_t和uint64_t
- Single-page app(SPA)
- 成功从小公司跳槽!java并发编程实践pdf完整百度云
- 一文告诉你什么是领域驱动设计?
- 小爱同学app安卓版_小爱同学app2.0.1 安卓版 下载 - 51下载网
- PADS 导入cadence dsn文件,同步pads layout
- Codeforces Round #531 F. Elongated Matrix (状压dp)
- kityminder-editor 百度脑图与my-mind 使用体验
- pcf8591简明教程 及 51单片机最大只能读到127问题解决
- 微信也能鉴别山寨iPhone【微信高级教程2】
- python详细安装教程-Pycharm及python安装详细教程(图解)
- 个人博客中MetingJS引用qq音乐列表歌单