mmap系统调用用法

时间:2011-12-09 12:38:47

标签: posix mmap

我听说使用mmap系统调用将两个内存块合并为一个连续的MAP_ANONYMOUS标志,但我找不到任何简单的例子如何使用这个技巧。

Wikipedia上实现优化循环缓冲区的示例对我来说太复杂了(Circular Buffer article)。

你能给我一个MAP_ANONYMOUS标志的用法示例吗?

1 个答案:

答案 0 :(得分:2)

根据您在评论中提供的说明,听起来您正试图弄错两件与彼此无关的事情。

void *part1 = malloc(100);
void *part2 = malloc(250);

您希望操纵虚拟内存,以便这两个内存块可以作为350个连续的内存字节进行寻址。

这是不可能的。首先,您拥有的内存块通常既不是页面对齐的,也不是页面大小的。您只能以页面对齐的页面大小的块来操作虚拟内存。其次,即使你很幸运,它们是页面对齐的和页面大小的,它们可能来自堆区域(brk()下面的区域)。我不认为您可以使用mremap()munmap()重新映射或取消映射该内存区域。 (有malloc()的替代实现从mmap()获取内存并且不会受到此问题的影响,但它们仍然存在第一个问题。

但是,假设您确实有两个页面对齐,页面大小和可重新映射的内存块,并且您希望重新映射它们以使它们相邻。最有可能的是,您首先从mmap()获得了这些块。然后,您可以使用mremap()将它们重新映射到相邻的地址。请注意,mremap()是特定于Linux的。我不知道有一种可移植的方式来做到这一点。在伪代码中:

/* Map some useless memory just to get the kernel to reserve a range
   of addresses for us which will be big enough for both blocks */
address = mmap(NULL, blocksize1+blocksize2, ..., MAP_ANONYMOUS, ...);

/* remap the first block to the the first address in this new range */
mremap(block1, blocksize1, blocksize1, MREMAP_MAYMOVE|MREMAP_FIXED, address);
/* remap the second block to go right after the first block */
mremap(block2, blocksize2, blocksize2, MREMAP_MAYMOVE|MREMAP_FIXED,
        address+blocksize1);