簡體   English   中英

將分配器添加到C ++類模板以創建共享內存對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM