[英]Adding an allocator to a C++ class template for shared memory object creation
簡而言之,我的問題是:如果您擁有類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);
但是,我不知道如何向類模板添加顯式分配器。
我認為您只是在尋找新的標准展示位置 。
如果shm_addr
是指向共享內存的void*
指針,則可以執行以下操作:
MyBuffer *pBuf = new (shm_Addr) MyBuffer;
並且新的MyBuffer
將在給定位置構造。 這可以與任何類型的對象一起使用,包括模板類型。
如果認為合適,可以將其包裝在單獨的函數中。
要銷毀使用標准放置新創建的內容,您需要顯式調用析構函數。 這是因為delete
會嘗試將內存new
分配為常規的new
分配內存,而這並不是一件有效的事情。 這是C ++中唯一需要顯式調用析構函數的時間。
pBuf->~MyBuffer();
讓我感到困惑的是,為什么需要在SharedMemory(SHM)中分配或創建對象,例如,如果保留大小為65536字節的共享內存,那么假設您的共享內存位於地址0x1ABC0000
,如果保留成功,您將在0x1ABC0000 to 0x1ABCFFFF
處有可用的直接訪問的內存空間。
然后,當您的應用程序需要在大小為sizeof(SHMObject)
SHM中“分配”對象,並且您的內存管理器看到0x1ABC0000+0x1A
處的地址是空閑的時,您的內存管理器應僅返回0x1ABC001A
值,並將( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) )
標記( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) )
已被占用,您只需要SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);
: SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);
當然,假設您有自己的自定義內存分配器,可以在指定的內存地址范圍內工作。
至於模板,我不太了解SHM環形緩沖區的樣子,但是在使用SHM之前,我已經做到了,我的實現是這樣的:
//memory SHM allocator
template<typename T> class ShmRingAllocator
{
protected:
void* baseAddress;
public:
ShmRingAllocator(void* baseAddress,int memSize);
void* allocate(); //this function do what I described earlier, or you can use placement new: new (baseAddress+offset)T;
}
//some kind of shared_ptr<> that handle object in SHM, this provides mechanishm to check is the pointer still valid in shm or not
template<typname T> ShmRingObjectPtr
{
protected:
T* object; //mapped address of object at current process
ShmBuffer* shm; //every object has pointer to which SHM does this pointer pointing at
public:
virtual T* operator->(); //operator overload to access T object
}
class ShmBuffer //base class for all kind of SHM buffer
{
protected:
std::string shmName;
void* shmBasePtr;
}
template<typename T,class A=ShmRingAllocator<T>> ShmRingBuffer : public ShmBuffer
{
protected:
A allocator;
public:
ShmRingObjectPtr<T> insert() //push one element to ring buffer
{
return ShmRingObjectPtr<T>((T*)this->allocator.allocate(),this);
}
}
`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.