Структура STL внутри Shared Memory

Мне нужно создать структуру, подобную очереди, внутри моей структуры, которую я использую в качестве общей памяти. Как я могу это сделать ? Мой компилятор Visual C++.


person Carlos    schedule 13.07.2013    source источник
comment
Попробуйте Boost.Interprocess.   -  person Kerrek SB    schedule 13.07.2013
comment
boost.org/doc/libs/1_54_0/doc/ html/межпроцесс/   -  person Flexo    schedule 13.07.2013
comment
разве это невозможно без использования внешних библиотек?   -  person Carlos    schedule 13.07.2013
comment
это действительно память, разделяемая другим процессом?   -  person alexbuisson    schedule 13.07.2013
comment
да. Один процесс создаст разделяемую память и поместит целые числа в очередь. и другой будет читать их.   -  person Carlos    schedule 13.07.2013
comment
Все возможно и без внешних библиотек, просто вам придется сделать гораздо больше работы, которую уже сделал кто-то другой.   -  person n. 1.8e9-where's-my-share m.    schedule 13.07.2013


Ответы (2)


Боюсь, использование сложного объекта C++ в разделяемой памяти не так просто. Вы должны учитывать две вещи.

1)

Вам нужно создать экземпляр класса в области разделяемой памяти, а не в стеке. Вы можете сделать это, используя новый оператор размещения. Пример:

#include <new> // for placement new operator

class X
{
     // whatever
};

// suppose this points to some shared memory area
void *shared_mem = getSharedMem();

// this creates an instance of X at the start address of shared_mem
new(shared_mem) X;

// now you have a reference to an instance of X in the shared memory area
X& shared_x = *reinterpret_cast<X*>(shared_mem);

Обратите внимание, однако, что только один процесс должен отвечать за создание этого объекта в разделяемой памяти. Также другим участвующим процессам нужны средства, чтобы узнать, правильно ли инициализирован объект и можно ли безопасно получить к нему доступ. Для доступа также требуется какая-то межпроцессная блокировка (например, в Win32 именованный мьютекс).

2)

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

Используемый класс распределителя является частью объявления шаблона STL. Например, std::deque‹T, A›, где A — тип распределителя. По умолчанию используется стандартный распределитель STL, который получает память из кучи.

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

В общем, вам может быть лучше написать простой пользовательский класс очереди, который работает с общей памятью, как описано в 1). Вы можете заставить класс очереди использовать память статического размера, например, он может содержать место ровно для 100 объектов в очереди, и если вы превысите этот предел, операция завершится ошибкой.

person gerrit zijlstra    schedule 13.07.2013
comment
Как другой процесс может получить доступ к объекту в разделяемой памяти? (Предположим, что объект был успешно инициализирован и другой процесс знает адрес разделяемой памяти) - person Carlos; 15.08.2013

  1. Используйте мьютекс для защиты вашей общей памяти независимо от типа данных или класса. Неважно, насколько сложны ваши данные. Также прочитайте это о как работают мьютексы и темы википедии. Ваши общие данные должны быть в куче или в виде глобальной переменной, но не в стеке, то есть не в локальной переменной.
  2. For all access of the data, you have to:
    • lock mutex
    • копировать данные или записывать в данные (не тратьте на это слишком много времени)
    • освободить мьютекс
    • использовать данные (если они скопированы)
  3. Вы хотите использовать легковесную мультиплатформенную библиотеку C++ с открытым исходным кодом для потоков и мьютексов? Попробуйте TinyThread++. Его лицензия также подходит для коммерческого использования, поскольку является свободной. Он состоит всего из 3 файлов. Пожалуйста, обратитесь к документации о том, как его использовать. Версия C: TinyCThread.
person ruben2020    schedule 13.07.2013