c++ - 使用 boost::interprocess 在共享内存中分配用户定义的结构

标签 c++ c++11 boost shared-memory boost-interprocess

我正在尝试使用 boost::interprocess 在共享内存中分配一个非常简单的数据结构,但我不太清楚如何使用 boost interprocess allocators在我按如下方式分配的共享内存段内执行内存分配/解除分配

using namespace boost::interprocess;
shared_memory_object::remove("MySharedMem");
mSharedMemory = std::make_unique<managed_shared_memory>(
    open_or_create, "MySharedMem", 65536);

我之前问过一个类似的question但不幸的是我从来没有得到任何答案。下面的 MyStruct 本质上是一个数组,长度字段指示数组的大小。现在我有一个简单的长度字段,但稍后我会添加一些其他构造函数参数(bool 和其他简单类型)。

为了在共享内存段中分配它,我知道我必须对分配器做一些事情,但我找不到类似的例子,我有一个包含数组/指针字段的用户定义类型。

    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());

最佳答案

只是不要进行手动分配。如果您想要连续分配 char 类型的 aSize 元素,这就是 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;
};

现在要很好地使用标准库构造/作用域分配器,您可能需要定义 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 命名空间中创建了一些方便的 typedef。这是完整的示例

完整样本

Live On Coliru ¹

#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 使用托管映射文件,因为那里不支持共享内存

关于c++ - 使用 boost::interprocess 在共享内存中分配用户定义的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46915878/

相关文章:

boost - 如何在 boost::geometry 中提供 IntersectionStrategy

c++ - 为什么我们需要 std::move 在构造函数的初始化列表中?

C++ 将另一个方法作为参数传递

c++ - Lambda 中数组衰减为指针

c++ - Boost 反序列化问题 : Input Stream Error at runtime (c++)

c++ - boost::managed_mapped_file 无法分配所有增长的空间

c++ - 在 DLL 中包含 OpenVDB;与 Visual Studio 2015 的链接错误

c++ - CMake:制作目标后如何写入文件?

c++ - 关于在构造函数中将临时绑定(bind)到引用成员的虚假警告

c++ - NULL 不匹配模板参数?