我可以要求我的任何响应者只考虑“纯”C/C++(无论这意味着什么)吗?STL 没问题。升压不是。
我正在编写自己的 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 对象数组被解释为最小堆,例如,我每次执行 new 和 delete 时都会终止堆属性。
- 如果我保证这个池不会用于最小堆(例如,根据定时器管理技术的需要),我们对上述方案有什么问题吗?
- 另一方面,我可以将共享内存中的 Foo 数组作为最小或最大堆进行管理(即,在新建和删除期间),并且每次新建或删除都会导致 O (lg n) 最坏情况。任何意见?
- 还有其他更好的方法吗?