2014-01-08 37 views
3

我对Boost库(对于Windows)的术语有点困惑。我想要做的只是简单的;在磁盘上创建一个文件(一个大文件> 50 GB),分别为写入和读取操作做一些映射。内存映射文件,托管映射文件和偏移指针

例如第一映射1 GB的部分为刷新它到硬盘驱动器后写&采取新的部分等等,而阅读器应用程序映射文件的不同部分,做阅读的东西不改变任何东西(没有编辑)。

我读升压的文件(因为我们允许使用这一个1.47.0版)和我完全不明白何时使用内存映射文件方法,如:file_mapping,managed_region和托管地图文件:例如basic_managed_mapped_file和Offset_Ptr。

任何人都可以告诉我内存映射文件和托管映射文件有什么区别,它们的用法是什么?

如果可能的话,一些示例代码会对这些和Offset_ptr高度适用。

谢谢确实...

回答

4

可以使用managed_mapped_file透明地从内存映射文件分配。

这意味着,对于所有的实际目的,你通常不需要对你的记忆区域进行再分配。无论如何它都是虚拟内存,因此分页需要在需要的时间加载正确的位。

很明显,如果有很多碎片或访问“跳来绕去”,那么分页可能会成为性能瓶颈。在这种情况下,考虑到细分池,并从这些分配。)_

编辑只注意到升压IPC有Segregated storage node allocatorsAdaptive pool node allocators下这种支持。还有关于这些存储池的实施的说明here

下面是一个创建一个50GB的文件,并在充塞一些数据的简单的出发点:

#include <iostream> 
#include <string> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

#include <boost/container/flat_map.hpp> 
#include <boost/container/flat_set.hpp> 

#include <boost/interprocess/managed_mapped_file.hpp> 
#include <boost/container/scoped_allocator.hpp> 
#include <boost/interprocess/containers/string.hpp> 
#include <boost/interprocess/containers/vector.hpp> 
#include <boost/interprocess/sync/named_mutex.hpp> 
#include <boost/interprocess/sync/scoped_lock.hpp> 

namespace bip = boost::interprocess; 
using mutex_type = bip::named_mutex; 

struct X 
{ 
    char buf[100]; 
    double rate; 
    uint32_t samples[1024]; 
}; 

template <typename T> using shared_alloc = bip::allocator<T,bip::managed_mapped_file::segment_manager>; 
template <typename T> using shared_vector = boost::container::vector<T, shared_alloc<T> >; 
template <typename K, typename V, typename P = std::pair<K,V>, typename Cmp = std::less<K> > 
         using shared_map = boost::container::flat_map<K, V, Cmp, shared_alloc<P> >; 

using shared_string = bip::basic_string<char,std::char_traits<char>,shared_alloc<char> >; 
using dataset_t  = shared_map<shared_string, shared_vector<X> >; 

struct mutex_remove 
{ 
    mutex_remove() { mutex_type::remove("7FD6D7E8-320B-11DC-82CF-39598D556B0E"); } 
    ~mutex_remove(){ mutex_type::remove("7FD6D7E8-320B-11DC-82CF-39598D556B0E"); } 
} remover; 

static mutex_type mutex(bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-39598D556B0E"); 

static dataset_t& shared_instance() 
{ 
    bip::scoped_lock<mutex_type> lock(mutex); 
    static bip::managed_mapped_file seg(bip::open_or_create,"./demo.db", 50ul<<30); // "50Gb ought to be enough for anyone" 

    static dataset_t* _instance = seg.find_or_construct<dataset_t> 
     ("DATA") 
     (
     std::less<shared_string>(), 
     dataset_t::allocator_type(seg.get_segment_manager()) 
     ); 

    static auto capacity = seg.get_free_memory(); 
    std::cerr << "Free space: " << (capacity>>30) << "g\n"; 

    return *_instance; 
} 

int main() 
{ 
    auto& db = shared_instance(); 

    bip::scoped_lock<mutex_type> lock(mutex); 
    auto alloc = db.get_allocator().get_segment_manager(); 

    std::cout << db.size() << '\n'; 

    for (int i = 0; i < 1000; ++i) 
    { 
     std::string key_ = "item" + std::to_string(i); 
     shared_string key(alloc); 
     key.assign(key_.begin(), key_.end()); 
     auto value = shared_vector<X>(alloc); 
     value.resize(size_t(rand()%(1ul<<9))); 
     auto entry = std::make_pair(key, value); 

     db.insert(std::make_pair(key, value)); 
    } 
} 

注意,它写了一个稀疏文件50G的。提交的实际大小取决于在那里的一些随机数。我的运行造成了大约1.1G:

$ du -shc --apparent-size demo.db 
50G demo.db 

$ du -shc demo.db 
1,1G demo.db 

希望这有助于

+0

感谢您的回答,但我不知道我理解所有清楚,因为它有点“高级别”对我来说。所以基本上我想要做的是为1个写入器应用程序和8个读取器应用程序构建一个缓冲区,以同时在sam机器上工作。作者将数据放入12 MB/s,阅读器应用程序会对缓冲区上的数据执行一些搜索和读取操作。所以我认为在磁盘上创建一个文件将某些部分映射到RAM中进行写入,然后将这部分内容刷新到磁盘。但对“如何”部分有点困惑。至少我是否正确? – user2955554

+0

只是一个补充:读者应用程序也应该对缓冲区上的数据进行一些搜索,以便他们也可以在地址空间上做一些映射操作。我需要那些您在上面告诉过的分离式存储节点分配器和自适应池节点分配器吗? – user2955554

+0

多个进程可以在同一时间将同一个文件(区域)映射到其进程空间_。这就是为什么你需要同步(我的示例中命名的互斥体)。没有必要刷新/读取,以便其他进程看到它。文件支持(仅)用于持久性。 – sehe