Как обеспечить совместную работу malloc и mmap, т. Е. Работать с неперекрывающимися областями памяти? - PullRequest
4 голосов
/ 26 февраля 2012

Моя основная проблема заключается в том, что мне нужно разрешить нескольким процессам ОС обмениваться данными через большую кучу общей памяти, которая сопоставлена ​​с одинаковыми диапазонами адресов во всех процессах. (Чтобы убедиться, что значения указателя действительно значимы.)

Теперь я сталкиваюсь с проблемой, что часть программы / библиотеки использует стандартный malloc / free, и мне кажется, что базовая реализация не учитывает отображения, которые я создаю с помощью mmap. Или другой вариант - я создаю отображения в регионах, которые malloc уже планировал использовать.

К сожалению, я не могу гарантировать 100% идентичное поведение malloc / free во всех процессах до того, как я установлю mmap-mappings.

Это приводит меня к присвоению флага MAP_FIXED для mmap. Первый процесс использует 0x0 в качестве базового адреса, чтобы гарантировать, что диапазон отображения, по крайней мере, как-то разумен, но, похоже, это не передается другим процессам. (Двоичный файл также связан с -Wl, -no_pie.)

Я попытался выяснить, могу ли я запросить систему, чтобы узнать, какие страницы она планирует использовать для malloc, прочитав malloc_default_zone , но этот API, похоже, не предлагает то, что мне нужно.

Есть ли способ убедиться, что malloc не использует определенные страницы памяти / диапазоны адресов?

(Он должен работать на OSX. Советы по Linux, которые направляют меня в правильном направлении, также приветствуются.)

Ответы [ 2 ]

3 голосов
/ 26 февраля 2012

Я замечаю это в документации mmap :

Если указано MAP_FIXED, успешный mmap удаляет все предыдущие сопоставления в выделенном диапазоне адресов

Однако malloc не будет использовать фиксированную карту, поэтому, пока вы заходите до malloc, все будет в порядке: вы можете проверить, свободен ли регион, сначала попытавшись отобразить его без MAP_FIXED, и если это удастся по тому же адресу (что он сделает, если адрес свободен), то вы можете переназначить с MAP_FIXED, зная, что вы не выбираете раздел адресного пространства, который malloc уже захватил

Единственный гарантированный способ гарантировать, что один и тот же блок логической памяти будет доступен в двух процессах, - это получить один ответвление от другого.

Однако, если вы компилируете с 64-битными указателями, тогда вы можете просто выбрать (необычную) область памяти и надеяться на лучшее, поскольку вероятность столкновения ничтожна.

См. Также этот вопрос о допустимых адресных пространствах.

0 голосов
/ 26 февраля 2012

Реализация malloc () в OpenBSD использует mmap () для выделения памяти. Я предлагаю вам посмотреть, как это работает, затем написать свою собственную реализацию malloc () и рассказать вашей программе и используемым им библиотекам использовать вашу собственную реализацию malloc ().

Вот OpenBSD malloc ():

http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/malloc.c?rev=1.140

РБ

...