文件空间映射mmap()函数(是什么,为什么,怎么用)
4.文件空间映射mmap()函数
是什么
1、mmap()函数用来将文件或者设备映射到内存中。 2、mmap的特点是按需调页。最开始只申请vma,并不调真正的页。当对某些页进行引用的时候,会引起一个缺页中断,再将页面调入到内存当中,这样避免了对内存的浪费。
为什么要用mmap()函数
mmap的优势: 操作文件就像操作内存一样,适合于对较大文件的读写。
mmap的缺点: 1、文件如果很小,比如60bytes,由于在内存当中的组织都是按页组织的,将文件调入到内存当中是一个页4k,这样其他的4096-60=4036 bytes的内存空间就会浪费掉了。 2、而且文件无法完成拓展,因为mmap到内存的时候,你所能够操作的范围就确定了,无法增加文件的长度。 3、如果系统频繁的使用mmap操作,而且每次mmap的size都不同,那么就会使得内存可能缺少足够的连续的内存空间。
那又怎么了,人家就是用来操作大型数据的。 当mmap的文件是page size的整数倍的时候,使用mmap调用看起来是最合适的,不会造成浪费。 你用其他方式来进行大量数据传递简直不理智。
怎么用
1、开启文件空间映射函数mmap()
#include <sys/mman.h>
void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);
//以下这点还是要再提一下的,开辟空间的时候要掂量掂量
/*
文件无法完成拓展,因为mmap到内存的时候,你所能够操作的范围就确定了,无法增加文件的长度。
*/
参数释义: start:用户所要映射的目的地址,一般放NULL,让系统自己去找。 length:顾名思义。 prot:映射区保护方式,取值范围 { PROT_EXEC:映射区可执行 PROT_READ:映射区可读取 PROT_WRITE:映射区可写入 PROT_NONE:映射区不可存取 }
如果要几个功能合在一起,用管道符 | 连通 当然,权限最高的还是映射的文件,如果被映射文件不让读,那就没办法读。
flags:对映射对象的配置 { MAP_FIXED:一般不用 MAP_SHARED:共享映射区 MAP_PRIVATE:读时共享,写时复制,对映射区的操作不会对原文件造成影响 MAP_ANONYMOUS:建立匿名映射,不涉及文件,所以用不到fd,也不允许与其他进程共享 MAP_DENYWRITE:对文件的写操作将被禁止,只能通过映射文件对原文件进行操作 MAP_LOCKED:将映射区锁定,不会被虚拟内存重置 } shared和private必须且只能选一个。
fd:代表文件的文件描述符。 offset:偏移量。一般设为0,表示从头开始映射。
2、解除映射函数munmap()
//系统调用munmap()
int munmap( void * addr, size_t len )
/*该调用在进程地址空间中解除一个映射关系,addr是调用mmap()时返回的地址,len是映射区的大小。当映射关系解除后,对原来映射地址的访问将导致段错误发生。*/
实例代码:
#include <sys/mman.h>;
#include <sys/types.h>;
#include <fcntl.h>;
#include <unistd.h>;
typedef struct
{
char name[4];
int age;
}people;
main(int argc, char** argv) // map a normal file as shared mem:
{
int fd,i;
people *p_map;
char temp;
fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,0777);
lseek(fd,sizeof(people)*5-1,SEEK_SET);
write(fd,"",1);
p_map = (people*) mmap( NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );
close( fd );
temp = 'a';
//直接使用这种写入方式
for(i=0; i<10; i++)
{
temp += 1;
memcpy( ( *(p_map+i) ).name, &temp,2 );
( *(p_map+i) ).age = 20+i;
}
printf(" initialize over /n ");
sleep(10);
munmap( p_map, sizeof(people)*10 );
printf( "umap ok /n" );
}
- iOS网络——NSURLSession详解及SDWebImage源码解析你要知道的NSURLSession都在这里
- BZOJ3585: mex(主席树)
- 01.LoT.UI 前后台通用框架分解系列之——小图片背景全屏显示(可自动切换背景)
- 02.LoT.UI 前后台通用框架分解系列之——灵活的菜单栏
- 05.LoT.UI 前后台通用框架分解系列之——漂亮的时间选择器
- 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传
- 07.LoT.UI 前后台通用框架分解系列之——轻巧的文本编辑器
- 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器
- 洛谷P3358 最长k可重区间集问题(费用流)
- 08.LoT.UI 前后台通用框架分解系列之——多样的Tag选择器
- iOS多线程——RunLoop与GCD、AutoreleasePool你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- iOS多线程——你要知道的RunLoop都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- iOS网络——AFNetworking AFHttpSessionManager源码解析
- iOS网络——SDWebImage SDImageDownloader源码解析你要知道的NSURLSession都在这里
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php curl获取https页面内容,不直接输出返回结果的设置方法
- 详解php中curl返回false的解决办法
- Pytorch mask-rcnn 实现细节分享
- pytorch中的weight-initilzation用法
- python安装读取grib库总结(推荐)
- PHP5.5新特性之yield理解与用法实例分析
- php如何利用pecl安装mongodb扩展详解
- PHP微信支付结果通知与回调策略分析
- PHP标准库(PHP SPL)详解
- php成功操作redis cluster集群的实例教程
- 在pytorch中动态调整优化器的学习率方式
- 可视化pytorch 模型中不同BN层的running mean曲线实例
- python如何删除文件、目录
- pytorch实现查看当前学习率
- python3.x中安装web.py步骤方法