将分配器添加到C ++类模板以创建共享内存对象

时间:2010-03-11 07:31:17

标签: c++ shared-memory allocator

简而言之,我的问题是:如果您有课程MyClass<T>,您如何更改课程定义以支持您拥有MyClass<T, Alloc>的情况,类似于STL矢量提供的情况。

我需要此功能来支持共享内存的分配器。具体来说,我试图在共享内存中实现一个环形缓冲区。目前它有以下ctor:

template<typename ItemType>
SharedMemoryBuffer<ItemType>::SharedMemoryBuffer( unsigned long capacity, std::string name )

其中ItemType是要放在缓冲区每个插槽中的数据类型。

现在,当我从主程序创建缓冲区时,这非常有效。

SharedMemoryBuffer<int>* sb;
sb = new SharedMemoryBuffer<int>(BUFFER_CAPACITY + 1, sharedMemoryName);

但是,在这种情况下,缓冲区本身不会在共享内存中创建,因此其他进程无法访问。我想做的是能够做类似

的事情
typedef allocator<int, managed_shared_memory::segment_manager>  ShmemAllocator;
typedef SharedMemoryBuffer<int, ShmemAllocator> MyBuffer;

managed_shared_memory segment(create_only, "MySharedMemory", 65536);
const ShmemAllocator alloc_inst (segment.get_segment_manager());
MyBuffer *mybuf = segment.construct<MyBuffer>("MyBuffer")(alloc_inst);

但是,我不知道如何在类模板中添加显式分配器。

2 个答案:

答案 0 :(得分:5)

我认为您只是在寻找标准展示位置新

如果shm_addr是指向共享内存的void*指针,则可以执行以下操作:

MyBuffer *pBuf = new (shm_Addr) MyBuffer;

将在给定位置构建新的MyBuffer。这适用于任何类型的对象,包括模板化类型。

如果您认为合适,可以将其包装在单独的函数中。

要销毁使用标准 placement new 创建的内容,您需要显式调用析构函数。这是因为delete会尝试将内存解除分配为常规new分配的内存,这不是一件有效的事情。这是C ++中唯一需要显式调用析构函数的时间。

pBuf->~MyBuffer();

答案 1 :(得分:3)

让我感到困惑的是,为什么需要在SharedMemory(SHM)中分配或创建对象,例如,如果您保留大小为65536字节的共享内存,则假设您在地址{{1}处获取共享内存},如果保留成功,您将在0x1ABC0000获得免费且可直接访问的内存空间。

然后,当您的应用程序需要在大小为0x1ABC0000 to 0x1ABCFFFF的SHM中“分配”对象,并且您的内存管理器看到sizeof(SHMObject)处的地址是免费的时,您的内存管理员应该返回0x1ABC0000+0x1A值,标记0x1ABC001A已被占用,您只需要投射:( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) )

andcourse假设你有自己的自定义内存分配器,它可以在指定的内存地址范围内工作。

至于模板,我真的不明白你的SHM环缓冲区是怎么样的,但是在使用SHM之前我已经这样做了,我的实现是这样的: `

SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);

`