使用 boost::interprocess 在共享内存中分配用户定义的结构
Allocating a user defined struct in shared memory with boost::interprocess
我正在尝试使用 boost::interprocess
在共享内存中分配一个非常简单的数据结构,但我不太清楚如何使用 boost interprocess allocators 在 allocations/deallocations 中执行内存我分配的共享内存段如下
using namespace boost::interprocess;
shared_memory_object::remove("MySharedMem");
mSharedMemory = std::make_unique<managed_shared_memory>(
open_or_create, "MySharedMem", 65536);
我之前问过类似的问题 question 但不幸的是我没有得到任何答案。下面的MyStruct
本质上是一个数组,长度字段表示数组的大小。现在我有一个简单的长度字段,但稍后我会添加一些其他构造函数参数(bool 和其他简单类型)。
为了在共享内存段中分配它,我知道我必须对分配器做一些事情,但我找不到类似的例子,我有一个包含 array/pointer 字段的用户定义类型。
using MyType = struct MyType {
explicit MyType(const size_t aSize)
: mSize(aSize)
, mpData(new char[aSize])
{}
~MyType() {
delete[]mpData;
}
size_t mSize;
char * mpData;
};
using MyTypeAllocator = boost::interprocess::allocator<MyType,
boost::interprocess::managed_shared_memory::segment_manager>;
// Initialize the shared memory STL-compatible allocator
MyTypeAllocator alloc(mSharedMemory->get_segment_manager());
只是不要进行手动分配。如果你想要 aSize
类型 char
元素的连续分配,这就是 C++ 具有 std::vector
的原因。
最重要的是,std::vector
已经知道如何使用另一个分配器,所以没有理由不使用它:
template <typename Alloc>
struct MyType {
explicit MyType(size_t aSize, Alloc alloc = {}) : mData(aSize, alloc) {}
private:
std::vector<char, Alloc> mData;
};
现在要很好地使用标准库 construct/scoped 分配器,您可能需要定义 allocator_type
嵌套类型:
using allocator_type = Alloc; // typename Alloc::template rebind<char>::other;
就是这样。只需将它用作具有分配器的任何标准库类型即可:
int main() {
using namespace Shared;
Shared::remove("MySharedMem");
auto memory = Segment(create_only, "MySharedMem", 65536);
using A = Alloc<char>;
A alloc(memory.get_segment_manager());
auto* data = memory.find_or_construct<MyType<A>>("data")(1024, memory.get_segment_manager());
return data? 0 : 255;
}
为了便于维护,我在 Shared
命名空间中创建了一些方便的类型定义。这是完整的示例
完整样本
#include <boost/interprocess/managed_shared_memory.hpp>
#include <vector>
template <typename Alloc>
struct MyType {
using allocator_type = typename Alloc::template rebind<char>::other;
explicit MyType(size_t aSize, Alloc alloc = {}) : mData(aSize, alloc) {}
private:
std::vector<char, Alloc> mData;
};
namespace Shared {
namespace bip = boost::interprocess;
using Segment = bip::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T>
using Alloc = bip::allocator<T, Manager>;
void remove(char const* name) { bip::shared_memory_object::remove(name); }
using bip::create_only;
}
int main() {
using namespace Shared;
Shared::remove("MySharedMem");
auto memory = Segment(create_only, "MySharedMem", 65536);
using A = Alloc<char>;
A alloc(memory.get_segment_manager());
auto* data = memory.find_or_construct<MyType<A>>("data")(1024, memory.get_segment_manager());
return data? 0 : 255;
}
¹ 因为 Coliru 使用托管映射文件,因为那里不支持共享内存
我正在尝试使用 boost::interprocess
在共享内存中分配一个非常简单的数据结构,但我不太清楚如何使用 boost interprocess allocators 在 allocations/deallocations 中执行内存我分配的共享内存段如下
using namespace boost::interprocess;
shared_memory_object::remove("MySharedMem");
mSharedMemory = std::make_unique<managed_shared_memory>(
open_or_create, "MySharedMem", 65536);
我之前问过类似的问题 question 但不幸的是我没有得到任何答案。下面的MyStruct
本质上是一个数组,长度字段表示数组的大小。现在我有一个简单的长度字段,但稍后我会添加一些其他构造函数参数(bool 和其他简单类型)。
为了在共享内存段中分配它,我知道我必须对分配器做一些事情,但我找不到类似的例子,我有一个包含 array/pointer 字段的用户定义类型。
using MyType = struct MyType {
explicit MyType(const size_t aSize)
: mSize(aSize)
, mpData(new char[aSize])
{}
~MyType() {
delete[]mpData;
}
size_t mSize;
char * mpData;
};
using MyTypeAllocator = boost::interprocess::allocator<MyType,
boost::interprocess::managed_shared_memory::segment_manager>;
// Initialize the shared memory STL-compatible allocator
MyTypeAllocator alloc(mSharedMemory->get_segment_manager());
只是不要进行手动分配。如果你想要 aSize
类型 char
元素的连续分配,这就是 C++ 具有 std::vector
的原因。
最重要的是,std::vector
已经知道如何使用另一个分配器,所以没有理由不使用它:
template <typename Alloc>
struct MyType {
explicit MyType(size_t aSize, Alloc alloc = {}) : mData(aSize, alloc) {}
private:
std::vector<char, Alloc> mData;
};
现在要很好地使用标准库 construct/scoped 分配器,您可能需要定义 allocator_type
嵌套类型:
using allocator_type = Alloc; // typename Alloc::template rebind<char>::other;
就是这样。只需将它用作具有分配器的任何标准库类型即可:
int main() {
using namespace Shared;
Shared::remove("MySharedMem");
auto memory = Segment(create_only, "MySharedMem", 65536);
using A = Alloc<char>;
A alloc(memory.get_segment_manager());
auto* data = memory.find_or_construct<MyType<A>>("data")(1024, memory.get_segment_manager());
return data? 0 : 255;
}
为了便于维护,我在 Shared
命名空间中创建了一些方便的类型定义。这是完整的示例
完整样本
#include <boost/interprocess/managed_shared_memory.hpp>
#include <vector>
template <typename Alloc>
struct MyType {
using allocator_type = typename Alloc::template rebind<char>::other;
explicit MyType(size_t aSize, Alloc alloc = {}) : mData(aSize, alloc) {}
private:
std::vector<char, Alloc> mData;
};
namespace Shared {
namespace bip = boost::interprocess;
using Segment = bip::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T>
using Alloc = bip::allocator<T, Manager>;
void remove(char const* name) { bip::shared_memory_object::remove(name); }
using bip::create_only;
}
int main() {
using namespace Shared;
Shared::remove("MySharedMem");
auto memory = Segment(create_only, "MySharedMem", 65536);
using A = Alloc<char>;
A alloc(memory.get_segment_manager());
auto* data = memory.find_or_construct<MyType<A>>("data")(1024, memory.get_segment_manager());
return data? 0 : 255;
}
¹ 因为 Coliru 使用托管映射文件,因为那里不支持共享内存