2014-01-08 35 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