6 Aralık 2017 Çarşamba

interprocess managed_mapped_file Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/list.hpp>
basic_managed_mapped_file sınıfı ile kardeştir.

Bu sınıf içinde bir segment manager kullanır. Açıklaması şöyle
Let's make a careful distinction between shared_memory_object (which is really low-tech and un-imposing) and managed_shared_memory/managed_mapped_file (which both use a segment_manager).
segment manager içinde control structures bulunur. Açıklaması şöyle
The managed segment constitutes, in essence, an auxiliary memory heap with its associated control structures.

It makes sense for the control structure to include details such as the actual extents of that "heap". Since the control structures are in the shared memory, they must be in the section already mapped into reading processes, too.

Changing the size of the memory segment would change values in that control structure which is visible from all processes mapping the same shared memory. This would obviously wreak havoc in processes that don't actually have enough memory mapped to satisfy the new extents (leading to page faults, at best).
Bellek Büyüklüğü
Açıklaması şöyle
Once a managed segment is created the managed segment can't be grown. The limitation is not easily solvable: every process attached to the managed segment would need to be stopped, notified of the new size, they would need to remap the managed segment and continue working. [...]
Tanımlama
Örnek
my_big_struct tipinden listeler tutan bir bellek alanı için şöyle yaparız.
namespace bip = boost::interprocess;

typedef int my_big_struct;

namespace shared {
  using segment = bip::managed_mapped_file;
  using manager = segment::segment_manager;

  template <typename T> using alloc = bip::allocator<T, manager>;
  template <typename T> using list  = boost::interprocess::list<T, alloc<T> >;
}

using List   = shared::list<my_big_struct>;
using ItList = shared::list<List::const_iterator>;
Constructor
Önce dosyayı temizlemek için şöyle yaparız.
std::remove("test.dat");
Ya da şöyle yaparız
std::string const fileName = "tmp.dat";
bip::file_mapping::remove(fileName.c_str());
Sonra dosyayı oluşturmak için şöyle yaparız.
bip::managed_mapped_file f (bip::open_or_create, "test.dat", 10u<<20); // 10 megabyte
Dosyayı yaratmak için şöyle yaparız
bip::managed_mapped_file f (bip::create_only, fileName.c_str(), 1l << 20);
Sadece okumak için şöyle yaparız.
bip::managed_mapped_file f (bip::open_only, "test.dat"); // read it back
Destructor
Nesne yok olunca dosya kaydedilir. Şöyle yaparız.
{
  bip::managed_mapped_file f (bip::open_or_create, "test.dat", 10u<<20); // 10 mb
  ...
}
// the file is persisted
construct metodu
Örnek
int içeren bir vector'ü doldurmak için şöyle yaparız. Vector'e allocator geçilir.
using intVec = std::vector<int, intAlloc>;

auto *vecObj = file.construct<intVec>("myVecName")(file.get_allocator<int>());

for (size_t i = 0; i < 10; i++) {
  vecObj->push_back(1 + 100);
}
Örnek
Şöyle yaparız. Nesneye allocator geçilir.
auto& buffer = *file.construct<Shared::Buffer>(bip::unique_instance)[1]
  (20, segment.get_segment_manager());

for (auto msg : { "hello", "world", "bye", "cruel", "world" })
  buffer.push(create(msg));
destroy metodu
construct metodu ile yaratılan nesneyi siler. Şöyle yaparız.
file.destroy<intVec>(bip::unique_instance);
find metodu
İsmi belirtilen segment varsa onu döndürür.

find_or_construct metodu
İsmi belirtilen segment varsa onu döndürür, yoksa yaratır
Örnek
Listeleri ve listeye iteratorleri ismen oluşturmak için şöyle yaparız.
auto& a = *file.find_or_construct<List>("a")(file.get_segment_manager());
auto& b = *file.find_or_construct<ItList>("b")(file.get_segment_manager());
auto& c = *file.find_or_construct<ItList>("c")(file.get_segment_manager());
Burada bellek içinde liste yaratılması ve kullanımını anlıyorum ancak iterator yaratılması ve kullanımı karışık geldi. İleride eğilmek üzere not aldım.

get_segment_manager metodu
Şöyle yaparız.
bip::managed_mapped_file file (bip::open_or_create, "test.bin", 10ull<<10);
auto* segment = file.get_segment_manager();
Segment'leri dolaşmak için şöyle yaparız.
for (auto it = segment->named_begin(); it != segment->named_end(); ++it) {
  std::cout << std::string(it->name(), it->name_length()) << "\n";
}
Yeni segment yaratmak için şöyle yaparız.
auto* segment = file.get_segment_manager();

for (auto segmentName : { "foo", "bar", "qux" }) {
  if (!file.find<V<int> >(segmentName).first)
  {
    file.find_or_construct<V<int> >(segmentName)(segment);
  }
}
Diğer
bip::file_mapping::remove metodu
Dosya silmek için şöyle yaparız
std::string const fileName = "tmp.dat";
bip::file_mapping::remove(fileName.c_str());
bip::shrink_to_fit metodu
Dosya kapandıktan sonra boyutunu küçültmek için şöyle yaparız.
std::string const fileName = "tmp.dat";
{
  bip::managed_mapped_file file = ...;
  ...
}

try { // Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
  bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
} catch (const std::exception &ex) {
  std::cerr << ex.what() << std::endl;
}

Hiç yorum yok:

Yorum Gönder