Adding a allocator to a C ++ class template to create a shared memory object

In short, my question is: if you have a class, MyClass<T>how can you change the class definition to support when you have it MyClass<T, Alloc>, similar to how, for example, the STL vector is provided.

I need this functionality to support a shared memory allocator. In particular, I am trying to implement a ring buffer in shared memory. He currently has the following ctor:

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

where ItemTypeis the type of data that should be placed in each slot in the buffer.

Now it works great when I create a buffer from the main program, this way

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

However, in this case, the buffer itself is not created in the shared memory and therefore is not available for other processes. I want to do something like

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);

, .

+3
2

, SharedMemory (SHM), , 65536 , , 0x1ABC0000, , 0x1ABC0000 to 0x1ABCFFFF.

, "" SHM sizeof(SHMObject), , 0x1ABC0000+0x1A , 0x1ABC001A ( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) ) > , : 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);
         }
}

`

+3

, .

shm_addr void* , :

MyBuffer *pBuf = new (shm_Addr) MyBuffer;

MyBuffer . , .

, .

-, , . , delete - new , . ++, .

pBuf->~MyBuffer();
+4

Source: https://habr.com/ru/post/1736445/


All Articles