将向量存储在内存映射文件中

Posted

技术标签:

【中文标题】将向量存储在内存映射文件中【英文标题】:Storing vector in memory mapped file 【发布时间】:2015-04-13 09:45:39 【问题描述】:

我正在尝试将任意元素的向量存储在内存映射文件中(现在我正在尝试使用整数向量取得成功,但它应该与任意对象的向量一起使用)。我找到了很多关于使用共享内存这样做的文档,但没有找到正确的内存映射文件。由于我已经成功地在内存映射文件中制作并使用了 R-trees(如在that example 中),我尝试使用向量复制该过程,但我想我错过了一些关键元素,因为它不起作用。这是我的代码:

namespace bi = boost::interprocess;
typedef bi::allocator<std::vector<int>, bi::managed_mapped_file::segment_manager> allocator_vec;
std::string vecFile = "/path/to/my/file/vector.dat";
bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), 1000);
allocator_vec alloc_vec(file_vec.get_segment_manager());
std::vector<int> * vecptr = file_vec.find_or_construct<std::vector<int> >("myvector")(alloc_vec);

可能我的最后一行是错误的,因为“alloc_vec”作为参数传递给了向量构造函数,它并不期望它 (我得到了错误/usr/include/c++/4.8/bits/stl_vector.h:248:7: note: candidate expects 0 arguments, 1 provided)。 但是,我不知道如何将分配器传递给 find_or_construc(),我认为这对于在内存映射文件中正确创建向量至关重要。删除最后一行末尾的 (alloc_vec) 会导致另一个错误,我很难解决:

error: cannot convert ‘boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>::construct_proxy<std::vector<int> >::type aka boost::interprocess::ipcdetail::named_proxy<boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index>, std::vector<int>, false>’ to ‘std::vector<int>*’ in initialization
std::vector<int> * vecptr = file_vec.find_or_construct<std::vector<int> >("myvector");

任何帮助将不胜感激。`

【问题讨论】:

总是有重载占用分配器,只是分配器与默认的Allocator模板参数类型(std::allocator&lt;T&gt;)不匹配(见en.cppreference.com/w/cpp/container/vector) 你为什么要尝试这个?为什么(为什么)你想要一个内存映射文件(一个低级的东西)中的向量(一个“高级容器”)。请编辑你的问题以改进它。 【参考方案1】:

就像示例显示的那样,告诉向量类你的自定义分配器,而不是

typedef std::vector<int>  MyVec;
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(alloc_vec);

使用

typedef bi::allocator<int, bi::managed_mapped_file::segment_manager> int_alloc;
typedef std::vector<int, int_alloc>  MyVec;

int_alloc alloc(file_vec.get_segment_manager());
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(alloc);

注意

vector 为元素类型使用分配器(不适用于向量;segment_manager 分配它) 由于allocator&lt;&gt; 的构造函数是隐式的,您也可以只传递segment_manager

Live On Coliru

#include <boost/interprocess/managed_mapped_file.hpp>

namespace bi = boost::interprocess;

int main() 
    std::string vecFile = "vector.dat";
    bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), 1000);

    typedef bi::allocator<int, bi::managed_mapped_file::segment_manager> int_alloc;
    typedef std::vector<int, int_alloc>  MyVec;

    MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(file_vec.get_segment_manager());

    vecptr->push_back(rand());

【讨论】:

您的代码在调试模式下在 MSVC14 上崩溃:***.com/q/51334785/2741329。你知道如何解决这个问题吗? 尝试删除 mm 文件并让它重新创建。也尝试改成 boost::container::vector 终于看到这个问题了:github.com/boostorg/interprocess/issues/58

以上是关于将向量存储在内存映射文件中的主要内容,如果未能解决你的问题,请参考以下文章

(转)Linux下内存映射文件的用法简介

高效率场景-内存映射

内存映射文件

存储映射IO

内存映射文件 IList 实现,用于“在内存中”存储大型数据集?

numpy 数组的内存映射文件