2

例如,如果我这样做:

  char *pMap1;          /* First mapping */
  char *pReq;           /* Address we would like the second mapping at */
  char *pMap2;          /* Second mapping */

  /* Map the first 1 MB of the file. */
  pMap1 = (char *)mmap(0, 1024*1024, PROT_READ, MAP_SHARED, fd, 0);
  assert( pMap1!=MAP_FAILED );

  /* Now map the second MB of the file. Request that the OS positions the
  ** second mapping immediately after the first in virtual memory.  */
  pReq = pMap1 + 1024*1024;
  pMap2 = (char *)mmap(pReq, 1024*1024, PROT_READ, MAP_SHARED, fd, 1024*1024);
  assert( pMap2!=MAP_FAILED );

  /* Unmap the mappings created above. */
  if( pMap2==pReq ){
    munmap(pMap1, 2 * 1024*1024);
  }else{
    munmap(pMap1, 1 * 1024*1024);
    munmap(pMap2, 1 * 1024*1024);
  }

并且操作系统确实将我的第二个映射放在请求的位置(以便 (pMap2==pReq) 条件为真),对 munmap() 的单次调用是否会释放所有分配的资源?

Linux 手册页说“munmap() 系统调用删除了指定地址范围的映射...”,这表明这将起作用,但我仍然对此有点紧张。即使它确实可以在 Linux 上运行,是否有人知道它的可移植性如何?

首先十分感谢。

4

3 回答 3

6

glibc 手册说没关系:

munmap删除从 (addr) 到 (addr + length) 的所有内存映射。length 应该是映射的长度。

在一个命令中取消映射多个映射是安全的,或者在范围中包含未映射的空间。也可以只取消现有映射的一部分。但是,只能删除整个页面。

于 2013-03-30T09:46:02.023 回答
3

POSIX 规范

int munmap(void *addr, size_t len);

munmap()函数应删除那些包含进程地址空间的任何部分的整个页面的任何映射,这些映射从字节开始addr并持续到len字节。

对我来说,措辞清楚地读起来好像用一个来删除多个映射munmap()很好,并且应该得到任何兼容实现的支持。

于 2013-03-30T08:50:47.053 回答
2

我认为它应该工作。POSIX 规范说它删除了

包含进程地址空间的任何部分的整个页面的任何映射,从字节开始addr并持续len字节

它描述的唯一未指定的行为是:

如果映射不是通过调用建立的,则此函数的行为是未指定的mmap()

于 2013-03-30T08:50:58.730 回答