调整共享匿名MMAP的大小

时间:2016-10-17 18:11:39

标签: c ipc mmap

比如说我创建了一个共享的匿名内存映射,如下所示:

segment = mmap(NULL, (100) * sizeof(int)), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
然后我做了一个分叉。我可以从子进程更改共享内存的大小吗?

2 个答案:

答案 0 :(得分:0)

这是我在书中所读到的" LINUX编程接口":

在大多数UNIX实现中,一旦创建了映射,就会显示其位置 和大小不能改变。但是,Linux提供了(不可移植的)mremap() 系统调用,允许这样的更改。 - 所以它主要取决于你是哪个操作系统。

On LINUX可以根据文档:

void *mremap(void *old_address, size_t old_size,
                    size_t new_size, int flags, ... /* void *new_address */);

我们必须提供新旧尺寸。

但是有一些限制和方案,这些操作可能没有任何影响或抛出错误。请仔细阅读文档: http://man7.org/linux/man-pages/man2/mremap.2.html

(在LINUX上)同时我没有看到来自子/其他进程的任何限制。 我的理解是,如果你能够获得共享内存地址,并且如果它是在没有任何锁定的情况下创建的,并且尝试修改共享内存的进程具有所需权限,我认为可以增加大小。

答案 1 :(得分:0)

根据这本优秀的书:How to strip decorators from a function in python(第1081页),Michael Kerrisk:

  

在大多数UNIX实现中,一旦创建了映射,就无法更改其位置和大小。但是,Linux提供了(不可移植的)mremap()系统调用,允许进行此类更改。

它还说明了以下内容:

  

成功时,mremap()返回映射的起始地址。由于(如果指定了MREMAP_MAYMOVE标志)该地址可能与先前的起始地址不同,则指向该区域的指针可能不再有效。因此,当引用映射区域中的地址时,使用mremap()的应用程序应仅使用偏移量(非绝对指针)(参见第48.6节)。