达尔文真的没有mmap吗?

我试图找出如何在Mac上重新映射内存映射文件(当我想扩展可用空间时)。

我看到我们在Linux世界中的朋友都有mremap但我在Mac上的标题中找不到这样的function。 /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h具有以下内容:

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • 但没有mremap

man mremap证实了我的恐惧。

如果我想调整映射文件的大小,我当前需要munmapmmmap ,这涉及使所有加载的页面无效。 肯定有更好的办法。 一定?

我正在尝试编写适用于Mac OS X和Linux的代码。 如果我必须这样做,我可以满足于在每种情况下使用最佳function的宏,但我宁愿正确地做。

您可以将文件设置为大尺寸(创建一个孔)并将其全部映射到mmap。 如果文件是持久的,我建议使用写入调用填充漏洞,而不是通过写入映射,否则文件的块可能会在磁盘上不必要地碎片化。

如果您需要缩小地图,只需在要删除的末尾处绘制零件。

如果你需要放大地图,你可以使用MAP_FIXED将正确的偏移量MAP_FIXED到旧地图上方的地址,但是你需要注意不要映射已经存在的其他东西……

罢工下的上述文字是一个可怕的想法; MAP_FIXED基本上是错误的,除非您已经知道目标地址处的内容并希望以primefaces方式替换它。 如果您尝试在地址范围空闲时机会性地映射新内容,则需要使用带有请求地址但没有 MAP_FIXED ,看看它是否成功并为您提供所请求的地址; 如果它成功但具有不同的地址,您将要取消映射刚刚创建的新映射,并假设无法在请求的地址进行分配。

如果扩展到足够大的块(例如,64 MB,但它取决于它的增长速度),那么使旧映射失效的成本可以忽略不计。 一如既往,在承担问题之前进行基准测试

我没有内存映射的经验,但看起来你可以暂时映射同一个文件两次,以扩展映射而不会丢失任何东西。

 int main() { int fd; char *fp, *fp2, *pen; /* create 1K file */ fd = open( "mmap_data.txt", O_RDWR | O_CREAT, 0777 ); lseek( fd, 1000, SEEK_SET ); write( fd, "a", 1 ); /* map and populate it */ fp = mmap( NULL, 1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); pen = memset( fp, 'x', 1000 ); /* expand to 8K and establish overlapping mapping */ lseek( fd, 8000, SEEK_SET ); write( fd, "b", 1 ); fp2 = mmap( NULL, 7000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); /* demonstrate that mappings alias */ *fp = 'z'; printf( "%c ", *fp2 ); /* eliminate first mapping */ munmap( fp, 1000 ); /* populate second mapping */ pen = memset( fp2+10, 'y', 7000 ); /* wrap up */ munmap( fp2, 7000 ); close( fd ); printf( "%d\n", errno ); } 

输出是zxxxxxxxxxyyyyyy....

我想,如果你这么做,可能会比使用mremap更快地耗尽地址空间。 但无论如何都没有任何保证,另一方面它可能同样安全。