使用boost :: interprocess在共享内存中分配用户定义的结构 [英] Allocating a user defined struct in shared memory with boost::interprocess

查看:303
本文介绍了使用boost :: interprocess在共享内存中分配用户定义的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用boost::interprocess在共享内存中分配一个非常简单的数据结构,但是我无法完全弄清楚如何使用

I am trying to use boost::interprocess to allocate a very simple data structure in shared memory but I cannot quite figure out how to use the boost interprocess allocators to perform the memory allocations/deallocations within the shared memory segment which I allocate as follows

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

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

I previously asked a similar question but unfortunately I never got any answers. MyStruct below is essentially an array with a length field indicating the size of the array. For now I have a simple length field but I will add some other constructor arguments later (bool's and other simple types).

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

In order to allocate this in the shared memory segment, I know I have to do something with allocators but I cannot find a similar example where I have a user defined type containing an array/pointer field.

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

推荐答案

只需不进行手动分配.如果要连续分配类型为charaSize元素,则C ++为此提供了std::vector.

Just don't do manual allocation. If you want a contiguous allocation of aSize elements of type char, that's what C++ has std::vector for.

最重要的是,std::vector已经知道如何使用另一个分配器,因此实际上没有理由不使用它:

Best of all, std::vector already knows how to use another allocator, so there is really no reason not to use it:

template <typename Alloc>
struct MyType {
    explicit MyType(size_t aSize, Alloc alloc = {}) : mData(aSize, alloc) {}

  private:
    std::vector<char, Alloc> mData;
};

现在,要与标准库构造/作用域分配器配合使用,您可能需要定义allocator_type嵌套类型:

Now to play well with standard library construct/scoped allocators, you might want to define the allocator_type nested type:

    using allocator_type = Alloc; // typename Alloc::template rebind<char>::other;

仅此而已.只需将其用作具有分配器的任何标准库类型:

That's all. Just use it as any standard library type that has an allocator:

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.这是完整的样本

I created a few convenience typedefs in the Shared namespace, for maintainability. Here's the full sample

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


¹ For Coliru uses managed mapped file because shared memory is not supported there

这篇关于使用boost :: interprocess在共享内存中分配用户定义的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆