1

在梳理了 Boost::Interprocess 文档和 Google 搜索之后,我想我已经找到了问题的原因/解决方法。据我了解,我发现的一切似乎都在暗示这一点,但并没有说“这样做是因为……”。但是,如果有人可以验证这一点,我将不胜感激。

我正在编写一系列类,这些类表示存储在内存中的大量信息查找,以便在并行化应用程序中实现快速性能。由于数据的大小和同时在一台机器上运行的多个进程,我们使用 Boost::Interprocess 共享内存来拥有结构的单个副本。

我查看了 Boost::Interprocess 文档和示例,它们为共享内存字符串、字符串向量、int 向量向量等 typedef 类。当他们在示例中“使用”它们时,他们只是通过分配器构造它们,也许插入他们在其他地方构建的一项。喜欢这个页面: http: //www.boost.org/doc/libs/1_42_0/doc/html/interprocess/allocators_containers.html

因此,按照他们的示例,我为共享内存类创建了一个带有 typedef 的头文件:

namespace shm {
    namespace bip = boost::interprocess;

    // General/Utility Types
    typedef bip::managed_shared_memory::segment_manager segment_manager_t;
    typedef bip::allocator<void, segment_manager_t> void_allocator;

    // Integer Types
    typedef bip::allocator<int, segment_manager_t> int_allocator;
    typedef bip::vector<int, int_allocator> int_vector;

    // String Types
    typedef bip::allocator<char, segment_manager_t> char_allocator;
    typedef bip::basic_string<char, std::char_traits<char>, char_allocator> string;
    typedef bip::allocator<string, segment_manager_t> string_allocator;
    typedef bip::vector<string, string_allocator> string_vector;
    typedef bip::allocator<string_vector, segment_manager_t> string_vector_allocator;
    typedef bip::vector<string_vector, string_vector_allocator> string_vector_vector;
}

然后对于我的一个查找表类,它的定义如下:

class Details {
public:
    Details(const shm::void_allocator & alloc) :
        m_Ids(alloc),
        m_Labels(alloc),
        m_Values(alloc) {
    }
    ~Details() {}

    int Read(BinaryReader & br);

private:
    shm::int_vector m_Ids;
    shm::string_vector m_Labels;
    shm::string_vector_vector m_Values;
};

int Details::Read(BinaryReader & br) {
    int num = br.ReadInt();

    m_Ids.resize(num);
    m_Labels.resize(num);
    m_Values.resize(num);

    for (int i = 0; i < num; i++) {
        m_Ids[i] = br.ReadInt();
        m_Labels[i] = br.ReadString().c_str();

        int count = br.ReadInt();
        m_Value[i].resize(count);
        for (int j = 0; j < count; j++) {
            m_Value[i][j] = br.ReadString().c_str();
        }
    }
}

但是当我编译它时,我得到了错误: 'boost::interprocess::allocator<T,SegmentManager>::allocator' : no appropriate default constructor available

这是由于对resize()矢量对象的调用。因为这些allocator类型没有空的构造函数(它们采用 a const segment_manager_t &)并且它试图为每个位置创建一个默认对象。所以为了让它工作,我必须得到一个分配器对象并传递一个默认值对象resize。像这样:

int Details::Read(BinaryReader & br) {
    shm::void_allocator alloc(m_Ids.get_allocator());
    int num = br.ReadInt();

    m_Ids.resize(num);
    m_Labels.resize(num, shm::string(alloc));
    m_Values.resize(num, shm::string_vector(alloc));

    for (int i = 0; i < num; i++) {
        m_Ids[i] = br.ReadInt();
        m_Labels[i] = br.ReadString().c_str();

        int count = br.ReadInt();
        m_Value[i].resize(count, shm::string(alloc));
        for (int j = 0; j < count; j++) {
            m_Value[i][j] = br.ReadString().c_str();
        }
    }
}

这是最好/正确的方法吗?或者我错过了什么。

谢谢!

4

0 回答 0