Создание объектов в разделяемой памяти C ++ - PullRequest
8 голосов
/ 23 декабря 2009

Нам нужно, чтобы несколько программ вызывали функции в общей библиотеке. Функции библиотеки обращаются и обновляют общую глобальную память. Вызовы функций каждой программы должны видеть эту общую глобальную память. То есть один вызов функции должен видеть обновления любого предыдущего вызова функции, даже если он вызывается из другой программы. По соображениям совместимости у нас есть несколько конструктивных ограничений на то, как должны работать функции, предоставляемые совместно используемой библиотекой:

  • Любые элементы данных (как стандартные типы данных, так и объекты), которые объявлены глобально, должны быть видны всем вызывающим сторонам независимо от потока, в котором выполняется код.
  • Любые элементы данных, которые объявлены локально в функции, видны только внутри этой функции.
  • Любой стандартный тип данных или экземпляр любого класса может отображаться либо локально, либо глобально, либо в обоих случаях.

Одним из решений является размещение общей глобальной памяти библиотеки в именованной общей памяти. Первый вызов библиотеки создаст именованную общую память и инициализирует ее. Последующие программные вызовы будут получать адрес разделяемой памяти и использовать его в качестве указателя на глобальную структуру данных. Экземпляры объекта, объявленные глобально, должны быть динамически размещены в разделяемой памяти, в то время как экземпляры объекта, объявленные локально, могут быть помещены в стек или в локальную кучу потока вызывающей стороны. Проблемы возникают из-за того, что инициализированные объекты в глобальной памяти могут создавать и указывать на подобъекты, которые выделяют (новую) дополнительную память. Эти новые распределения также должны быть в общей памяти и видны всем вызывающим библиотекам. Другая сложность заключается в том, что эти объекты, которые содержат строки, файлы и т. Д., Также могут использоваться в вызывающей программе. При объявлении в вызывающей программе память объекта является локальной для вызывающей программы, а не разделяемой. Таким образом, код объекта должен обрабатывать любой случай. Нам кажется, что решение потребует, чтобы мы переопределили глобальное размещение новых, регулярных новых и удаленных операторов. Мы нашли проект для системы управления памятью, который выглядит так, как будто она будет работать, но мы не нашли реальных реализаций. Если кто-то знает о реализации проекта управления памятью Натана Майерса (http://www.cantrip.org/wave12.html?seenIEPage=1)), я был бы признателен за ссылку на него. В качестве альтернативы, если кто-то знает о другом диспетчере совместно используемой памяти, который поддерживает динамическое размещение объектов, я хотел бы знать о нем как хорошо. Я проверил библиотеки Boost и все другие источники, которые я могу найти, но, похоже, ничего не делает то, что нам нужно. Мы предпочитаем не писать их сами. Поскольку производительность и надежность важны, было бы неплохо использовать проверенный код Заранее спасибо за любые идеи / помощь.

Спасибо за предложения по библиотекам ATL и OSSP. Я проверяю их сейчас, хотя боюсь, что ATL слишком винсентричен, если целью является Unix.

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

Ответы [ 4 ]

1 голос
/ 23 декабря 2009

Взгляните на boost.interprocess .

0 голосов
/ 23 декабря 2009

Также изучите мьютексы и семафоры. Когда двум или более объектам необходимо совместно использовать память или данные, должен существовать механизм «трафика», чтобы ограничить доступ на запись только одному пользователю.

0 голосов
/ 23 декабря 2009

Как я уверен, вы обнаружили, что это очень сложная проблема, и ее очень трудно правильно реализовать. Несколько советов из моего опыта. Прежде всего, вы определенно захотите синхронизировать доступ к распределенным ресурсам общей памяти с помощью семафоров. Во-вторых, любые модификации общих объектов несколькими процессами также должны быть защищены семафорами. Наконец, при определении ваших объектов и структур данных вам нужно думать о смещениях от начала области совместно используемой памяти, а не об абсолютных значениях указателя (как правило, память может отображаться по разному адресу в каждом присоединенном процессе. , хотя вы можете выбрать фиксированный адрес сопоставления, если вам нужно). Собрать все вместе надежным способом - трудная часть. Структуры данных на основе общей памяти легко повредить, если процесс неожиданно прекратит работу, поэтому обычно требуется какой-то механизм очистки / восстановления.

0 голосов
/ 23 декабря 2009

OSSP мм - Распределение общей памяти:

человек 3 мм

...