Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将分配器添加到C++;用于创建共享内存对象的类模板_C++_Shared Memory_Allocator - Fatal编程技术网

C++ 将分配器添加到C++;用于创建共享内存对象的类模板

C++ 将分配器添加到C++;用于创建共享内存对象的类模板,c++,shared-memory,allocator,C++,Shared Memory,Allocator,简言之,我的问题是:如果您有类,MyClass,如何更改类定义以支持您有MyClass的情况,类似于STL vector提供的方式 我需要这个功能来支持共享内存的分配器。具体来说,我试图在共享内存中实现一个环形缓冲区。目前它有以下特点: template<typename ItemType> SharedMemoryBuffer<ItemType>::SharedMemoryBuffer( unsigned long capacity, std::string name

简言之,我的问题是:如果您有类,
MyClass
,如何更改类定义以支持您有
MyClass
的情况,类似于STL vector提供的方式

我需要这个功能来支持共享内存的分配器。具体来说,我试图在共享内存中实现一个环形缓冲区。目前它有以下特点:

template<typename ItemType>
SharedMemoryBuffer<ItemType>::SharedMemoryBuffer( unsigned long capacity, std::string name )
但是,在这种情况下,缓冲区本身不是在共享内存中创建的,因此其他进程无法访问。我想做的是能够做像

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);
typedef分配器ShmemAllocator;
typedef SharedMemoryBuffer MyBuffer;
托管共享内存段(仅创建“MySharedMemory”,65536);
const ShmemAllocator alloc_inst(段.get_段管理器());
MyBuffer*mybuf=segment.construct(“MyBuffer”)(alloc_inst);

但是,我不知道如何向类模板添加显式分配器

我认为您只是在寻找新的标准位置

如果
shm_addr
是指向共享内存的
void*
指针,则可以执行以下操作:

MyBuffer *pBuf = new (shm_Addr) MyBuffer;
新的
MyBuffer
将在给定位置构建。这可以用于任何类型的对象,包括模板化类型

如果您认为合适,可以将其包装在单独的函数中

要销毁使用标准placement new创建的内容,需要显式调用析构函数。这是因为
delete
会尝试将内存作为常规
new
分配的内存进行反分配,这是无效的。这是C++中唯一需要显式调用析构函数的时间。

pBuf->~MyBuffer();

让我感到困惑的是,为什么需要在SharedMemory(SHM)中分配或创建一个对象,例如,如果您保留大小为65536字节的共享内存,那么假设您的共享内存位于地址
0x1ABC0000
,如果预订成功,您将在
0x1ABC0000到0x1ABCFFFF
处拥有可用的、可直接访问的内存空间

然后,当您的应用程序需要在大小为
sizeof(SHMObject)
的SHM中“分配”对象,并且您的内存管理器看到
0x1ABC0000+0x1A
处的地址是空闲的时,您的内存管理器只需返回
0x1ABC001A
值,并标记
(0x1ABC001A到0x1ABC001A+sizeof(SHMObject))
已被占用,您只需要强制转换:
SHMObject*shmObjectPtr=(SHMObject*)(0x1ABC001A)

当然,这是假设您有自己的自定义内存分配器,在指定的内存地址范围内工作

至于模板,我不太了解您的SHM环形缓冲区是什么样子的,但在使用SHM之前,我已经这样做了,我的实现如下: `

//内存SHM分配器
模板类ShmRingAllocator
{
受保护的:
空*基地址;
公众:
ShmRingAllocator(void*基地址,int memSize);
void*allocate();//此函数执行我前面描述的操作,也可以使用placement new:new(baseAddress+offset)T;
}
//某种在SHM中处理对象的共享ptr,这提供了检查指针在SHM中是否仍然有效的机制
模板ShmRingObjectPtr
{
受保护的:
T*object;//当前进程中对象的映射地址
ShmBuffer*shm;//每个对象都有一个指针,该指针指向shm
公众:
虚拟T*运算符->();//访问T对象的运算符重载
}
类ShmBuffer//所有类型SHM缓冲区的基类
{
受保护的:
std::字符串shmName;
无效*shmBasePtr;
}
模板ShmRingBuffer:公共ShmBuffer
{
受保护的:
分配器;
公众:
ShmRingObjectPtr insert()//将一个元素推送到环形缓冲区
{
返回ShmRingObjectPtr((T*)this->allocator.allocate(),this);
}
}

`

我不太明白你在问什么。您需要知道如何将模板参数添加到类模板中(在这种情况下,您可能需要显示类的当前定义),还是只需要知道如何在内存中的给定位置构造对象(在这种情况下,您应该搜索新位置)。无论哪种方式,我都会非常小心地将非POD对象放入共享内存。有可能从一个过程构建而从另一个过程破坏吗?你完全确定所有的类成员都能处理这个问题吗?我想我的问题可以简单地解释为:如何在共享内存中创建对象(而不是在当前进程的堆上创建对象并让它使用共享内存)。在这种情况下,你需要新的位置。e、 g.如果
shm_addr
是指向共享内存的
void*
指针,则可以执行
MyBuffer*pBuf=new(shm_addr)MyBuffer和新的
MyBuffer
将在给定位置构建。@Charles的问题变得模糊,因为我对共享内存的理解目前还不稳定。我实现了一个环形缓冲区,它使用共享内存来存储值。我希望不同的进程能够读取/写入缓冲区(实际上我有一个写入程序和多个读取程序)。我想这就是我想要的。我不知道你可以为
新建
指定地址位置,哇。谢谢您的SHM缓冲原型非常有用,谢谢!我有点理解您使用自定义SHM分配器实现它的方式。我无法理解的是,您如何从不同的进程、写入程序和读取程序访问ShmBuf。比如说,我在writer中创建ShmBuf并将元素插入其中。独立的读卡器进程如何访问该对象并从中读取数据(您似乎也没有pop()成员)。如果您希望不同的进程能够写入和读取数据,我可以通过创建offset_ptr来解决此问题。这与shared_ptr类似,但包含64位指针地址(在x86平台上),
pBuf->~MyBuffer();
//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);
         }
}