文件空间映射mmap()函数(是什么,为什么,怎么用)

举报
看,未来 发表于 2020/12/30 01:12:45 2020/12/30
【摘要】 4.文件空间映射mmap()函数 是什么 1、mmap()函数用来将文件或者设备映射到内存中。 2、mmap的特点是按需调页。最开始只申请vma,并不调真正的页。当对某些页进行引用的时候,会引起一个缺页中断,再将页面调入到内存当中,这样避免了对内存的浪费。 为什么要用mmap()函数 mmap的优势: 操作文件就像操作内存一样,适合于对较大文件的读写。 mm...

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到内存的时候,你所能够操作的范围就确定了,无法增加文件的长度。
*/

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

参数释义:
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是映射区的大小。当映射关系解除后,对原来映射地址的访问将导致段错误发生。*/


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

实例代码:

#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" );
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/105010136

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。