2016-10-17 10 views
2

Скажет, например, что я создал общую анонимную карту памяти, как один под:Изменение размера совместно анонимный MMAP

segment = mmap(NULL, (100) * sizeof(int)), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 

то, что я делаю вилку. Могу ли я изменить размер разделяемой памяти из дочернего процесса?

ответ

0

Это то, что я прочитал в книге «LINUX интерфейс программирования»:

В большинстве реализаций UNIX, когда отображение было создано, его местонахождение и размер не может быть изменен. Однако Linux предоставляет системный вызов (nonportable) mremap() , который допускает такие изменения. - Так что это в первую очередь зависит от того, какая ОС вы есть.

На 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) В то же время я не видел никаких ограничений от детского/другого процесса. Я понимаю, что если вы можете получить адрес общей памяти и если он создан без каких-либо блокировок, и процесс, который пытается изменить общую память, потребовал привилегий, я думаю, что размер может быть увеличен.

+0

Я не могу удалить свой предыдущий комментарий. В любом случае, спасибо за хороший ответ! Однако, если адрес в общей памяти изменится, дети больше не смогут получить к нему доступ. Возможно, есть способ заставить повторное использование адреса? –

+0

Может быть. Сначала я думал, что это невозможно. – Naidu

+0

В соответствии с [Kernel Bug Tracker] (https://bugzilla.kernel.org/show_bug.cgi?id=8691) 'mremap' с' MAP_SHARED' не поддерживается. – nwellnhof

0

По этой прекрасной книге: LINUX programming interface (p.1081) по Майкл Керриску:

В большинстве реализаций UNIX, когда отображение было создано, его расположение и размер не могут быть изменены. Однако Linux предоставляет системный вызов (nonportable) mremap(), который допускает такие изменения.

Он также утверждает следующее:

В случае успеха, mremap() возвращает начальный адрес отображения. Поскольку (если указан флаг MREMAP_MAYMOVE), этот адрес может отличаться от предыдущего стартового адреса, указатели в область могут перестать быть действительными. Поэтому приложения, использующие mremap(), должны использовать только смещения (не абсолютные указатели) при обращении к адресам в отображаемой области (см. Раздел 48.6).