简体   繁体   English

内存映射文件,托管映射文件和偏移指针

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

I'm a little bit confused about the terminology of Boost Library (for windows). 我对Boost Library(用于Windows)的术语有点困惑。 What I'm trying to do is simply; 我想做的只是简单; create a file on disk (a big file >50 GB) do some mapping for write and read operations seperately. 在磁盘上创建一个文件(一个大文件> 50 GB)单独为写入和读取操作做一些映射。

For example first map 1 gb portion for writing & after that flush it to the hard drive take a new portion and so on, while the reader applications maps different parts of the file and do the reading stuff without changing anything (no edit). 例如,第一个映射1 gb部分用于写入和之后将其刷新到硬盘驱动器采用新的部分,依此类推,而读取器应用程序映射文件的不同部分并执行读取操作而不更改任何内容(无编辑)。

I'm reading the documentation of boost (1.47.0 version since we allowed to use this one) and I don't understand exactly when to use Memory Mapped Files methods like: file_mapping, managed_region and Managed Map File : basic_managed_mapped_file and Offset_Ptr for instance. 我正在阅读boost(1.47.0版本,因为我们允许使用这个)的文档,我不明白何时使用内存映射文件方法,如:file_mapping,managed_region和托管映射文件 :basic_managed_mapped_file和Offset_Ptr例如。

Can anyone please tell me what is the difference between Memory Mapped Files and Managed Mapped File and what are the usages of them? 任何人都可以告诉我内存映射文件和托管映射文件之间的区别是什么?它们的用途是什么?

Some example codes would be highly apopriciated about these and Offset_ptr as well if possible. 如果可能的话,一些示例代码将高度关注这些和Offset_ptr。

Thank you indeed... 谢谢你......

You can use the managed_mapped_file to transparently allocate from a memory mapped file. 您可以使用managed_mapped_file从内存映射文件透明地分配。

This means that for all practical purposes you often don't need to dubdivide your memory areas. 这意味着,出于所有实际目的,您通常不需要重复划分您的记忆区域。 It's all virtual memory anyways, so paging takes care of loading the right bits at the required times. 无论如何它都是虚拟内存,因此分页负责在所需的时间加载正确的位。

Obviously, if there's a lot of fragmentation or accesses "jumping around" then paging might become a performance bottleneck. 显然,如果有很多碎片或访问“跳转”,那么分页可能会成为性能瓶颈。 In that case, consider subdividing into pools and allocate from those.)_ 在这种情况下,请考虑细分为池并从中进行分配。)_

Edit Just noticed Boost IPC has support for this under Segregated storage node allocators and Adaptive pool node allocators . 编辑刚刚注意到Boost IPC在隔离存储节点分配器自适应池节点分配器下支持此功能。 There are also notes about the implementation of these storage pools here . 此处还有关于这些存储池的实现的说明。

Here's a simple starting point that creates a 50Gb file and stuffs some data in it: 这是一个简单的起点,可以创建一个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));
    }
}

Note that it writes a sparse file of 50G. 请注意,它会写入50G的稀疏文件。 The actual size commited depends on a bit of random there. 提交的实际大小取决于那里的一点随机。 My run resulted in a roughly 1.1G: 我的跑步导致大约1.1G:

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

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

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM