2010-01-25 3 views
1

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

Независимо от этого, он взаимодействует с внешними модулями CGI, используя кусок разделяемой памяти, где хранится почти все его изменчивое состояние, чтобы внешние модули могли его прочитать и изменить там, где это применимо.

Проблема в том, что для модулей CGI требуется много постоянных конфигурационных данных из .so, а главное приложение выполняет совершенно ненужное копирование между двумя областями памяти, чтобы сделать данные доступными. Идея состоит в том, чтобы сделать весь общий объект загруженным в общую память и сделать его доступным непосредственно для CGI. Проблема в следующем: как?

  • dlopen и dlsym не предоставляют каких-либо средств для назначения места для загрузки SO-файла.
  • Мы попробовали shmat(). Кажется, что это работает только до тех пор, пока какой-то внешний CGI не попытается получить доступ к общей памяти. Тогда область, на которую указывает, выглядит так же конфиденциально, как если бы она никогда не делилась. Может быть, мы делаем что-то неправильно?
  • Загрузка .so в каждый скрипт, который в этом нуждается, не может быть и речи. Явный размер структуры, связанный с частотой вызовов (некоторые сценарии вызывают один раз в секунду для создания живых обновлений), и это встроенное приложение делает его недействительным.
  • просто memcpy() в .so в shm тоже нехорошо - некоторые структуры и все функции взаимосвязаны с помощью указателей.

ответ

2

Я полагаю, что самым простым вариантом было бы использовать файл с отображением памяти, который уже предложил Нейл. Если этот параметр не заполняется хорошо, альтернативой может быть определение выделенного распределителя. Вот хорошая статья об этом: Creating STL Containers in Shared Memory

Существует также отличная библиотека Boost.Interprocess Ion Gaztañaga с shared_memory_object и связанные функции.Ион предложил решение комитета по стандартизации C++ для будущего TR: Memory Mapped Files And Shared Memory For C++ , что может указывать на то, что стоит рассмотреть вопрос.

+0

Хотя это прямо не отвечает на мой вопрос, я думаю, что это самое ближайшее. Мне еще предстоит увидеть полезный вызов shmat() со вторым параметром, отличным от NULL. –

+0

Оставьте это NULL и дайте системе определить местоположение сегмента памяти, находящегося в состоянии ожидания, и верните ему свой адрес. – mloskot

2

Размещение реальных объектов C++ в общей памяти очень, очень сложно, как вы уже нашли. Я бы настоятельно рекомендовал, чтобы вы не пошли таким путем - размещение данных, которые необходимо использовать в общей памяти, или файл с отображением памяти намного проще и, вероятно, будет гораздо более надежным.

3

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

При загрузке файла .so загружается только одна копия кода файла .so (следовательно, термин совместно используемый объект).

fork также может быть вашим другом здесь. В большинстве современных операционных систем реализована семантика copy-on-write. Это означает, что когда вы fork, ваши сегменты данных копируются только в отдельную физическую память, когда один процесс записывает в данный сегмент данных.

0

Вам необходимо реализовать объект Serialization . Функция сериализации преобразует ваш объект в байты, тогда вы можете писать байты в SharedMemory и иметь ваш CGI-модуль для десериализации байтов обратно на объект.

+0

Боюсь, я не могу сериализовать функции C. –

 Смежные вопросы

  • Нет связанных вопросов^_^