簡體   English   中英

內存映射文件,托管映射文件和偏移指針

[英]Memory Mapped Files, Managed Mapped File and Offset Pointer

我對Boost Library(用於Windows)的術語有點困惑。 我想做的只是簡單; 在磁盤上創建一個文件(一個大文件> 50 GB)單獨為寫入和讀取操作做一些映射。

例如,第一個映射1 gb部分用於寫入和之后將其刷新到硬盤驅動器采用新的部分,依此類推,而讀取器應用程序映射文件的不同部分並執行讀取操作而不更改任何內容(無編輯)。

我正在閱讀boost(1.47.0版本,因為我們允許使用這個)的文檔,我不明白何時使用內存映射文件方法,如:file_mapping,managed_region和托管映射文件 :basic_managed_mapped_file和Offset_Ptr例如。

任何人都可以告訴我內存映射文件和托管映射文件之間的區別是什么?它們的用途是什么?

如果可能的話,一些示例代碼將高度關注這些和Offset_ptr。

謝謝你......

您可以使用managed_mapped_file從內存映射文件透明地分配。

這意味着,出於所有實際目的,您通常不需要重復划分您的記憶區域。 無論如何它都是虛擬內存,因此分頁負責在所需的時間加載正確的位。

顯然,如果有很多碎片或訪問“跳轉”,那么分頁可能會成為性能瓶頸。 在這種情況下,請考慮細分為池並從中進行分配。)_

編輯剛剛注意到Boost IPC在隔離存儲節點分配器自適應池節點分配器下支持此功能。 此處還有關於這些存儲池的實現的說明。

這是一個簡單的起點,可以創建一個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

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM