可以使用managed_mapped_file
透明地從內存映射文件分配。
這意味着,對於所有的實際目的,你通常不需要對你的記憶區域進行再分配。無論如何它都是虛擬內存,因此分頁需要在需要的時間加載正確的位。
很明顯,如果有很多碎片或訪問「跳來繞去」,那麼分頁可能會成爲性能瓶頸。在這種情況下,考慮到細分池,並從這些分配。)_
編輯只注意到升壓IPC有Segregated storage node allocators和Adaptive 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
希望這有助於
感謝您的回答,但我不知道我理解所有清楚,因爲它有點「高級別」對我來說。所以基本上我想要做的是爲1個寫入器應用程序和8個讀取器應用程序構建一個緩衝區,以同時在sam機器上工作。作者將數據放入12 MB/s,閱讀器應用程序會對緩衝區上的數據執行一些搜索和讀取操作。所以我認爲在磁盤上創建一個文件將某些部分映射到RAM中進行寫入,然後將這部分內容刷新到磁盤。但對「如何」部分有點困惑。至少我是否正確? – user2955554
只是一個補充:讀者應用程序也應該對緩衝區上的數據進行一些搜索,以便他們也可以在地址空間上做一些映射操作。我需要那些您在上面告訴過的分離式存儲節點分配器和自適應池節點分配器嗎? – user2955554
多個進程可以在同一時間將同一個文件(區域)映射到其進程空間_。這就是爲什麼你需要同步(我的示例中命名的互斥體)。沒有必要刷新/讀取,以便其他進程看到它。文件支持(僅)用於持久性。 – sehe