简而言之,我的问题是:如果您有类,MyClass T,您如何更改类定义以支持您拥有MyClass T,Alloc的情况,类似于STL vector提供的方式. 我需要此功能来支持共享内存的分配器.具体来说,我试图在共享
我需要此功能来支持共享内存的分配器.具体来说,我试图在共享内存中实现一个环形缓冲区.目前它有以下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到0x1ABCFFFF处有可自由且可直接访问的存储空间.然后当你的应用程序需要在大小sizeof(SHMObject)的SHM中“分配”对象,并且你的内存管理器看到0x1ABC0000 0x1A的地址是空闲时,你的内存管理器应该只返回0x1ABC001A值,并标记(0x1ABC001A到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); } }
`