Добавление распределения в шаблон класса C ++ для создания объекта общего

StackOverflow https://stackoverflow.com/questions/2423270

  •  19-09-2019
  •  | 
  •  

Вопрос

Короче говоря, мой вопрос: если у вас есть класс, 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);

Тем не менее, я не знаю, как добавить явный распределитель в шаблон класса.

Это было полезно?

Решение

Что заставляет меня запутать, зачем вам выделить или создать объект в Sharedmemory (SHM), например, если вы оставляете общую память о размере 65536 байтов, то предположим, что вы получаете общую память по адресу. 0x1ABC0000, если у вас будет бесплатное и непосредственно доступное пространство памяти при 0x1ABC0000 to 0x1ABCFFFF.

Затем, когда ваше заявление должно «распределить» объект в размере размера 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);
         }
}

`

Другие советы

Я думаю, что вы просто ищете стандарт размещение нового.

Если shm_addr это void* указатель на общую память, которую вы можете сделать:

MyBuffer *pBuf = new (shm_Addr) MyBuffer;

и новый MyBuffer будет построен в данном месте. Это может работать с любым типом объекта, включая шаблонные типы.

Вы можете обернуть это в отдельную функцию, если вы видите нужным.

Уничтожить что -то созданное со стандартным размещение нового Вам нужно явно назвать деструктор. Это потому что delete попытался бы разоблачить память как регулярную new выделенная память, которая не была бы достоверной задачей. Это единственный раз в C ++, который вам нужно явно назвать деструктором.

pBuf->~MyBuffer();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top