Резервирование общей памяти без поддержки файлов (Linux / Windows) (boost :: interprocess) - PullRequest
2 голосов
/ 18 сентября 2011

Как я могу зарезервировать и выделить общую память без резервной копии файла?Я пытаюсь зарезервировать большой (много десятков ГиБов) кусок общей памяти и использовать его в нескольких процессах в качестве формы IPC.Тем не менее, большая часть этого блока не будет затронута вообще (доступ будет очень редким; возможно, несколько сотен мегабайт на протяжении всего жизненного цикла процессов), и меня не волнуют данные, когда приложения заканчиваются.

Поэтому желательно, чтобы метод для этого имел следующие свойства:

  1. Не фиксирует весь диапазон.Я выберу, какие части зафиксировать (на самом деле использовать.) (Но шаблон довольно непредсказуемый.)
  2. Не требуется отображенный в памяти файл или что-то подобное.Мне не нужно сохранять данные.
  3. Позволяет мне получить доступ к области памяти из нескольких процессов (я буду явно обрабатывать блокировку).
  4. Работает как в Linux, так и в Windows (очевидно,Требуется 64-битная ОС.)
  5. На самом деле используется общая память.Мне нужна производительность.
  6. ( NEW ) ОС или библиотека не пытается инициализировать зарезервированную область (нулю или что-то в этом роде). Это, очевидно, нецелесообразно и не нужно.

Я экспериментировал с boost :: interprocess :: shared_memory_object, но из-за этого в файловой системе создается большой файл (того же размера, что и моя область отображенной памяти.) Он действительно удаляет файлвпоследствии, но это вряд ли поможет.

Любая помощь / совет / указатели / ссылки приветствуются.

PS Я действительно знаю, как сделать это в Windows, используя собственный API.И POSIX, кажется, обладает той же функциональностью (только с более чистым интерфейсом!). Я ищу кроссплатформенный способ здесь.

ОБНОВЛЕНИЕ: Я немного покопался, иоказывается, что поддержка, которая, как я думал, существовала в Windows, была лишь частным случаем файлов с отображением в памяти, используя файл системной страницы в качестве основы.(Я никогда раньше этого не замечал, потому что в прошлых проектах я использовал не более нескольких мегабайт общей памяти.)

Кроме того, теперь у меня есть новое требование (число 6 выше).

1 Ответ

1 голос
/ 07 марта 2012

В Windows вся память должна быть так или иначе поддержана диском.

Самое близкое, что, я думаю, вы можете сделать в Windows - это карта памяти разреженного файла. Я думаю, что это будет работать в вашем случае по двум причинам:

  1. В Windows только разделяемая память, к которой вы фактически прикасаетесь, станет резидентной. Это соответствует первому требованию.
  2. Поскольку файл является разреженным, только части, которые были изменены, будут фактически сохранены на диске. Если вы посмотрите на свойства файла, он скажет что-то вроде: «Размер: 500 МБ, Размер на диске: 32 КБ».

Я понимаю, что это технически не соответствует вашему второму требованию, но, к сожалению, я не думаю, что это возможно в Windows. По крайней мере, при таком подходе только регионы, которые вы фактически используете, будут занимать пространство. (И только когда Windows решает зафиксировать память на диске, что она может или не может делать по своему усмотрению.)

Что касается превращения этого в кроссплатформенное решение, одним из вариантов будет изменение boost :: interprocess, чтобы он создавал разреженные файлы в Windows. Я считаю, что boost :: interprocess уже отвечает вашим требованиям в Linux, где доступна общая память POSIX.

...