我的主要问题是我需要启用多个操作系统进程,以通过映射到所有进程中相同地址范围的大型共享内存堆进行通信。 (确保指针值实际上有意义。)
现在,我遇到麻烦,程序/库的一部分使用标准的malloc / free,在我看来底层实现不尊重我用mmap创建的映射。 或者,另一个选择是我在malloc已计划使用的区域中创建映射。
不幸的是,在建立mmap-mappings之前,我无法保证在所有进程中100%完全相同的malloc / free行为。
这导致我将MAP_FIXED标志提供给mmap。第一个进程使用0x0作为基址,以确保映射范围至少在某种程度上是合理的,但似乎不会转移到其他进程。 (二进制文件也与-Wl,-no_pie链接。)
我试图弄清楚是否可以通过阅读malloc_default_zone来查询系统以了解它计划用于malloc的哪些页面,但该API似乎没有提供我需要的内容。
有没有办法确保malloc没有使用特定的内存页/地址范围?
(它需要在OSX上工作。指导我正确方向的Linux技巧也很受欢迎。)
答案 0 :(得分:3)
我在mmap
documentation中注意到了这一点:
如果指定了MAP_FIXED,则成功的mmap将删除分配的地址范围内的任何先前映射
但是,malloc
不会使用固定的地图,所以只要你在malloc之前进入,你就可以了:你可以先测试一个区域是否空闲,而不用{{ 1}},如果在相同的地址成功(如果地址是免费的,它将会执行),那么您可以使用MAP_FIXED
重新映射,因为您知道您没有选择{{1}的地址空间部分已经抓住了
保证两个进程中同一块逻辑内存可用的唯一保证方法是从另一个进程中获得一个fork。
但是,如果您正在使用64位指针进行编译,那么您可以选择一个(不寻常的)内存区域,并希望获得最佳效果,因为碰撞的可能性很小。
另请参阅this question有关有效地址空间的信息。
答案 1 :(得分:0)
OpenBSD malloc()实现使用mmap()进行内存分配。我建议你看看它是如何工作然后编写你自己的malloc()自定义实现,并告诉你的程序和它使用的库使用你自己的malloc()实现。
这是OpenBSD malloc():
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c?rev=1.140
RBA