2019-10-14 mmap,mremap,munmap,msync

mmap,mremap,munmap,msync详解

文章目录

  • mmap,mremap,munmap,msync详解
    • mmap
      • 概述:
      • 函数:
      • 应用:
    • mremap
      • 概述:
      • 函数:
      • 应用:
      • munmap
        • 概述:
        • 函数:
      • msync
        • 概述:
        • 函数:

mmap

概述:

一种内存映射文件的方法:

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。即映射长度最小都是一内存页。

mmap操作提供了一种机制,让用户程序直接访问设备内存,这种机制,相比较在用户空间和内核空间互相拷贝数据,效率更高。在要求高性能的应用中比较常用。mmap映射内存必须是页面大小的整数倍,面向流的设备不能进行mmap,mmap的实现和硬件有关。

文件一旦被映射后,调用mmap()的进程对返回地址的访问是对某一内存区域的访问,暂时脱离了磁盘上文件的影响。只有在调用了munmap()后或者msync()时,才把内存中的相应内容写回磁盘文件,所写内容仍然不能超过文件的大小。

函数:

#include 
函数原型
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);

参数:
start:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址。
length:映射区的长度。//长度单位是 以字节为单位,不足一内存页按一内存页处理
prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通
过 | 运算合理地组合在一起

	PROT_EXEC //页内容可以被执行
	PROT_READ //页内容可以被读取
	PROT_WRITE //页可以被写入
	PROT_NONE //页不可访问
	
flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者
	   多个以下位的组合体
    MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重
    叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会
    失败。并且起始地址必须落在页的边界上。
    MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,
    相当于输出到文件。
    MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文
    件。这个标志和MAP_SHARED标志是互斥的,只能使用其中一个。
    MAP_DENYWRITE //这个标志被忽略。
    MAP_EXECUTABLE //同上
    MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区
    修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引
    起段违例信号。
    MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。
    MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。
    MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。
    MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。
    MAP_FILE //兼容标志,被忽略。
    MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当
    前这个标志只在x86-64平台上得到支持。
    MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不
    会被页违例阻塞。
    MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已
    存在于内存中的页面建立页表入口。
    
fd:有效的文件描述词。一般是由open()函数返回,其值也可以设置为-1,此时需要指
定flags参数中的MAP_ANONYMOUS,表明进行的是匿名映射,只能用于具有亲缘关系的进
程间通信。
off_toffset:被映射对象内容的起点。

返回值:
成功执行时,mmap()返回被映射区的指针。失败时,mmap()返回MAP_FAILED。

应用:

mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

mremap

概述:

重新映射虚拟内存地址。

函数:

#include 

void * mremap(void * old_address ,size_t old_size ,
			size_t new_size ,int flags ,... / * void * new_address  * /;

参数:
old_address:是您所使用的虚拟内存块的旧地址想要扩大(或缩小)。注意old_address必须是页面对齐
old_size:是虚拟内存块的旧大小。如果old_size的值为零,则mremap()将创建
       	  相同页面的新映射。new_size将是新映射的大小。
new_size:是请求后虚拟内存块的大小。
flags:默认情况下,如果没有足够的空间在当前位置展开映射,则  mremap()失败。
	MREMAP_MAYMOVE:允许内核将映射重定位到新的虚拟地址。
	MREMAP_FIXED  (从Linux 2.3.31开始)
	mremap()接受第五个参数  void * new_address,该参数指定映射必须移至页
	面对齐地址。在new_address和new_size指定的地址范围内的所有先前映射都不会
	被映射。如果指定了MREMAP_FIXED,还必须指定MREMAP_MAYMOVE。
	
new_address:可选择映射地址的位置,也可NULL,系统返回映射地址。

返回值:
成功时,mremap()返回一个指向新虚拟内存区域的指针。
错误时,将返回值MAP_FAILED

应用:

修改文件后,文件大小发生改变,通常与ftruncate()连用,ftruncate()用于修改文件大小,然后进行可进行重新映射mremap()。

int ftruncate(int fd,off_t length);
功能:
将参数fd指定的文件大小改为参数length指定的大小。

返回值:
执行成功则返回0,失败返回-1。

munmap

概述:

用来解除内存映射。当进程结束或利用exec相关函数来执行其他程序时,映射内存会自动解除,但关闭对应的文件描述符时不会解除映射。

函数:

 #include
 
 int munmap(void *start,size_t length);
 
  参数:
  start:所指的映射内存起始地址。
  length:取消的内存大小。
  
  返回值:
  如果解除映射成功则返回0,否则返回-1

msync

概述:

刷新映射空间的对共享内容的改变,写到磁盘,使磁盘文件内容与共享内存区中的内容一致。往往在调用munmap()后才执行该操作。

函数:

#include

int msync ( void * addr, size_t len, int flags);

参数:
	addr:文件映射到进程空间的地址;
	len:映射空间的大小;
	flags:刷新的参数设置:
		  MS_ASYNC(异步)时,调用会立即返回,不等到更新的完成;
		  MS_SYNC(同步)时,调用会等到更新完成之后返回;
		  MS_INVALIDATE(通知使用该共享区域的进程,数据已经改变)时,在共享
		  内容更改之后,使得文件的其他映射失效,从而使得共享该文件的其他进程
		  去重新获取最新值;
		  
返回值:
成功则返回0;失败则返回-1;

你可能感兴趣的:(linux)