例如,如果我这样做:
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上运行, 有人知道这可能是多么便携吗?
非常感谢。
答案 0 :(得分:5)
glibc手册说没关系:
munmap 将所有内存映射从(addr)移除到(addr + length)。长度 应该是映射的长度。
取消映射多个是安全的 在一个命令中映射,或包括范围中的未映射空间。它是 也可以仅取消映射现有映射的一部分。但是,只有 整个页面都可以删除。
答案 1 :(得分:3)
POSIX规范says:
int munmap(void *addr, size_t len);
munmap()
函数应删除包含从addr
开始并继续len
字节的进程地址空间的任何部分的整个页面的任何映射。强>
对我而言,措辞清楚地表明好像删除多个映射只有一个munmap()
是正常的,并且应该得到任何合规实现的支持。
答案 2 :(得分:2)
我认为它应该有效。 POSIX spec表示删除了
包含从
addr
开始并继续len
字节的流程地址空间的任何部分的整个页面的任何映射
它描述的唯一未指明的行为是:
如果未通过调用
mmap()
建立映射,则未指定此函数的行为。