Linux系统调用mmap和mmap2,创建一个进程地址空间的映射,mmap/mmap2几个常用的场景:

1. 文件映射普通文件I/O操作,读写mmap映射后的内存,即可完成文件的读写操作,kernel和userspace操作同一块物理内存;而常规的文件读写,需要循环调用read write lseek接口,每一次读写都需要kernel到userspace,或者userspace到kernel的内存拷贝。因此mmap方式操作提升了文件访问速度。但是mmap映射由于占用了大量内存将影响其他操作所能使用的内存数量(尽管kernel会在内存紧缺的时候回收内存)。

如果要映射的文件很大,最好的做法是对文件进行分段映射,虽然linux进程的线性地址空间很大,但是仍然有限。

2. 使用mmap匿名映射,在调用mmap时,设置一个特殊的标志MAP_ANONYMOUS。匿名映射可以用来分配较大的内存区,userspace可以显示的调用mmap分配内存;此外,libc中使用malloc分配内存时,如果申请的内存是一小块内存(比如小于某一个临界值),malloc会调用brk从进程地址空间的堆分配内存,否则直接调用mmap/mmap2分配内存。

在内核中,brk的实现实际上是简化版本的do_mmap实现,brk假定线性区不映射磁盘上的文件。

3. 共享内存映射。主要用于进程间通讯,对于映射的任何修改,对其他映射这个文件的进程都是可见的,并且修改结果都会反映到下面的文件。和管道,消息队列等进程通信方式,共享内存效率更高。


mmap和mmap2

C标准库使用统一的函数入口mmap函数来创建映射,mmap的C库实现会选择mmap或者mmap2来进行实际的映射创建。

在kernel系统调用级则提供了两个系统调用 mmap和mmap2。mmap和mmap2的区别在于参数offset,这个参数指定了文件映射的起始位置,对于mmap单位是bytes,而对于mmap2单位则是PAGE_SIZE


MAP_LOCKED和MAP_UNLOCKED

MAP_LOCKED使得进程虚拟地址空间映射的page不再处于缺页状态,某些情况下不希望访问线性地址被交换到交换空间。

MAP_UNLOCKED的作用正好相反

Logo

更多推荐