繁体   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