0
点赞
收藏
分享

微信扫一扫

mmap - 永远滴神

RockYoungTalk 2021-09-25 阅读 119

用处:1、分配内存,一般是超过128K的malloc会使用mmap的系统调用

        2、读写大文件

        3、链接动态库文件

        4、多进程间共享内存

...

Linux头文件: #include<sys/mman.h>

安卓C库文件:android/bionic/libc/bionic/mmap.cpp

void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
int munmap(void* __addr, size_t __size);

mmap -> mmap64

参数介绍

addr:用于指定映射到进程虚拟空间的起始地址,为了提高可移植性,一般设为NULL,让内核分配合适的地址

size:映射到进程地址空间的大小

prot:内存映射区域的读写属性(PROT_EXRC/PROT_READ/PROT_WRITE/PROT_NONE)

flags:内存映射的属性,如共享映射,私有映射

  • MAP_SHARED:创建一个共享映射区域,多个进程可以通过共享映射方式来映射一个文件,修改后的内容会同步到磁盘
  • MAP_PRIVATE:私有写时复制的映射,多个进程可以通过私有映射方式来映射一个文件,修改后的内容不会同步到磁盘
  • MAP_ANONYMOUS:没有关联到文件的映射
  • MAP_FIXED:使用参数addr创建映射,按页对齐,如果addr+length和已有VMA重叠,则销毁重新映射
  • MAP_POPULATE:文件映射提前预读内容,只支持私有映射

fd:文件映射的句柄

offset:文件映射时的偏移量

void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
  if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
    errno = EINVAL;
    return MAP_FAILED;
  }

  // prevent allocations large enough for `end - start` to overflow
  size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
  if (rounded < size || rounded > PTRDIFF_MAX) {
    errno = ENOMEM;
    return MAP_FAILED;
  }

  bool is_private_anonymous =
      (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
  bool is_stack_or_grows_down = (flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;

  void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);

  if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
      is_private_anonymous && !is_stack_or_grows_down) {
    ErrnoRestorer errno_restorer;
    int rc = madvise(result, size, MADV_MERGEABLE);
    if (rc == -1 && errno == EINVAL) {
      kernel_has_MADV_MERGEABLE = false;
    }
  }

  return result;
}

来了,排列组合

  • 私有匿名映射,fd=-1, flags=MAP_ANONYMOUS|MAP_PRIVATE, glibc分配大内存块(超过128K)代替brk
  • 共享匿名映射,fd=-1,,flags=MAP_ANONYMOUS|MAP_SHARED,常用于父子进程通信,共享一块内存区域
  • 私有文件映射,MAP_PRIVATE,加载动态共享库
  • 共享文件映射,1.读写文件 2.进程间通信
举报

相关推荐

0 条评论