Мне нужно создать структуру, подобную очереди, внутри моей структуры, которую я использую в качестве общей памяти. Как я могу это сделать ? Мой компилятор Visual C++.
Структура STL внутри Shared Memory
Ответы (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 объектов в очереди, и если вы превысите этот предел, операция завершится ошибкой.
- Используйте мьютекс для защиты вашей общей памяти независимо от типа данных или класса. Неважно, насколько сложны ваши данные. Также прочитайте это о как работают мьютексы и темы википедии. Ваши общие данные должны быть в куче или в виде глобальной переменной, но не в стеке, то есть не в локальной переменной.
- For all access of the data, you have to:
- lock mutex
- копировать данные или записывать в данные (не тратьте на это слишком много времени)
- освободить мьютекс
- использовать данные (если они скопированы)
- Вы хотите использовать легковесную мультиплатформенную библиотеку C++ с открытым исходным кодом для потоков и мьютексов? Попробуйте TinyThread++. Его лицензия также подходит для коммерческого использования, поскольку является свободной. Он состоит всего из 3 файлов. Пожалуйста, обратитесь к документации о том, как его использовать. Версия C: TinyCThread.