将分配器添加到 C++用于创建共享内存对象的类模板
简而言之,我的问题是:如果您有类 MyClass
,如何更改类定义以支持您有 MyClass
的情况,类似于 STL 矢量提供的方式。
我需要此功能来支持共享内存分配器。具体来说,我正在尝试在共享内存中实现环形缓冲区。目前它具有以下构造函数:
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);
但是,我不知道如何向类模板添加显式分配器。
In short, my question is: If you have class, MyClass<T>
, how can you change the class definition to support cases where you have MyClass<T, Alloc>
, similar to how, say, STL vector provides.
I need this functionality to support an allocator for shared memory. Specifically, I am trying to implement a ring buffer in shared memory. Currently it has the following ctor:
template<typename ItemType>
SharedMemoryBuffer<ItemType>::SharedMemoryBuffer( unsigned long capacity, std::string name )
where ItemType
is the type of the data to be placed in each slot of the buffer.
Now, this works splendid when I create the buffer from the main program thus
SharedMemoryBuffer<int>* sb;
sb = new SharedMemoryBuffer<int>(BUFFER_CAPACITY + 1, sharedMemoryName);
However, in this case the buffer itself is not created in shared memory and so is not accessible to other processes. What I want to do is to be able 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);
However, I don't know how to go about adding an explicit allocator to the class template.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您只是在寻找标准的新展示位置。
如果
shm_addr
是一个指向共享内存的void*
指针,您可以这样做:并且新的
MyBuffer
将在给定位置构造。这可以适用于任何类型的对象,包括模板化类型。如果您认为合适,可以将其包装在一个单独的函数中。
要销毁使用标准放置 new 创建的内容,您需要显式调用析构函数。这是因为
delete
会尝试将内存作为常规new
分配的内存来取消分配,这不是有效的操作。这是 C++ 中唯一一次需要显式调用析构函数。I think that you are just looking for the standard placement new.
If
shm_addr
is avoid*
pointer to shared memory you can do:and the new
MyBuffer
will be constructed at the given location. This can work with any type of object, including templated types.You can wrap this in a separate function if you see fit.
To destroy something created with standard placement new you need to explicitly call the destructor. This is because
delete
would try to de-allocate the memory as regularnew
allocated memory which wouldn't be a valid thing to do. This is the only time in C++ that you need to explicitly call a destructor.让我困惑的是,为什么你需要在 SharedMemory (SHM) 中分配或创建一个对象,例如,如果你保留大小为 65536 字节的共享内存,那么假设你在地址
0x1ABC0000
,如果预约成功,您将在0x1ABC0000 至 0x1ABCFFFF
拥有可用且可直接访问的内存空间。然后,当您的应用程序需要在 SHM 中“分配”大小为
sizeof(SHMObject)
的对象,并且您的内存管理器发现0x1ABC0000+0x1A
处的地址空闲时,您的内存管理器应该只返回0x1ABC001A
值,并标记( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) )
已被占用,并且您只需要转换:SHMObject* shmObjectPtr = ( SHMObject*)(0x1ABC001A);
当然,这是假设您有自己的自定义内存分配器,可以在指定的内存地址范围内工作。
至于模板,我不太明白你的SHM环形缓冲区是什么样子的,但我在使用SHM之前已经这样做了,我的实现是这样的:
`
`
what make me confuse is, why you need to allocate or create an object in SharedMemory (SHM), for example if you reserve shared memory of the size 65536 Bytes, then suppose you get your shared memory at address
0x1ABC0000
, if reservation success you will have free and directly accessible memory space at0x1ABC0000 to 0x1ABCFFFF
.then when your application need to "allocate" object in SHM of size
sizeof(SHMObject)
, and your memory manager see that address at0x1ABC0000+0x1A
is free, your memory manager should just return0x1ABC001A
value, and mark( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) )
was occupied, and you just need to cast:SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);
and ofcourse that is assuming you have your own custom memory allocator that work on specified range of memory address.
as for template, i don't really understand how does your SHM ring buffer look like, but I've done that before using SHM, my implementation is like this:
`
`