Могу ли я попросить любого респондента рассмотреть только «чистый» C / C ++ (что бы это ни значило)?STL в порядке.Boost - это не.
Я пишу свой собственный класс пула памяти C ++ (в системе Linux) для размещения и освобождения объектов C ++ в разделяемой памяти.Мне это нужно для доступа к одним и тем же объектам в нескольких процессах.Я буду контролировать доступ к манипулированию объектами пула памяти с помощью семафоров POSIX, но у меня возник вопрос о базовом распределении / освобождении.Мой код будет работать только для объектов одного размера, выделяемых из одного и того же пула.На данный момент мы можем игнорировать проблемы, связанные с динамическим увеличением и сокращением пула.
Учтите, что у меня есть сегмент общей памяти, определенный для общего количества объектов MAXFOOOBJECTS Foo.Я определяю сегмент разделяемой памяти следующим образом:
int shmid = shmget (somekey, ((sizeof(Foo) + 4) * MAXFOOOBJECTS) + 4, correctFlags);
void* sMem = shmat (shmid, (void*)0, 0);
Для всех процессов, использующих эту разделяемую память, память будет интерпретироваться следующим образом:
struct SharedMemStructure
{
int numberOfFooObjectsInPool;
Foo* ptrArray [MAXFOOOBJECTS]; // Pointers to all the objects in the array below
Foo objects [MAXFOOOBJECTS]; // Same as the value in the shmget call
};
Допустим, яиметь объект Foo, определенный следующим образом:
<Foo.h>
class Foo
{
public:
Foo ();
~Foo ();
void* operator new (); // Will allocate from shared memory
void operator delete (void* ptr); // Will deallocate from shared memory
private:
static void* sharedMem; // Set this up to be a POSIX shared memory that accesses
// the shared region in memory
static int shmid;
}
<Foo.cpp>
int Foo::shmid = shmget (somekey, ((sizeof(Foo) + 4) * MAXFOOOBJECTS) + 4, correctFlags);
void* Foo::sharedMem = shmat (shmid, (void*)0, 0);
void* Foo::operator new ()
{
void* thisObject = NULL;
sem_wait (sem); // Implementation of these is not shown
// Pick up the start of a chunk from sharedMem (will make sure this
// chunk has unused memory...
thisObject = (sharedMem + 4 + 4 * MAXFOOOBJECTS +
(sizeof (Foo) * sharedMem->numberOfFooObjectsInPool);
sharedMem->ptrArray[numberOfFooObjectsInPool] = thisObject;
sharedMem->numberOfFooObjectsInPool ++;
sem_post (sem);
return thisObject;
}
void Foo::operator delete (void* ptr)
{
int index = 0;
sem_wait (sem); // Implementation of these is not shown
// Swap the deleted item and the last item in the ptrArray;
index = (ptr - (sharedMem + 4 + (4*MAXFOOOBJECTS)))/(sizeof(Foo));
ptrArray[index] == ptrArray[numberOfFooObjectsInPool - 1];
numberOfFooObjectsInPool --;
sem_post (sem);
}
Теперь мои вопросы:
- Кажется ли вышеупомянутая схема приемлемой для вас, ребята (O (1) для каждого из новыхи удалить) или я что-то упустил очень важное?Одна проблема, которую я сразу вижу, состоит в том, что, если массив объектов Foo интерпретируется, например, как min heap, я уничтожаю свойство heap каждый раз, когда делаю новое и удаляю.
- Если я гарантирую, что этот пул не будет использоваться для минимальной кучи (скажем, как того требуют методы управления таймером), есть ли у нас какие-либо проблемы с вышеупомянутой схемой?
- С другой стороны, я мог бы управлять массивом Foo в разделяемой памяти как минимальной или максимальной кучей (т. Е. При обновлении и удалении) и получать O (lg n) наихудший случай для каждогоновый или удалить.Любые комментарии?
- Любой другой способ, который предпочтительнее?