Как получить список именованных объектов в общей межпроцессорной памяти Boost

Согласно руководству по Boost Docs

Возможно создание именованных векторов некоторого типа (например, двойного)

  using namespace boost::interprocess;
  typedef allocator<int, managed_shared_memory::segment_manager>  ShmemAllocator;
  managed_shared_memory segment(create_only, "MySharedMemory", 65536);

  //Initialize shared memory STL-compatible allocator
  const ShmemAllocator alloc_inst (segment.get_segment_manager());

  //Construct a vector named "values_A" in shared memory with argument alloc_inst
  MyVector *vA= segment.construct<MyVector>("values_A")(alloc_inst);
  MyVector *vB= segment.construct<MyVector>("values_B")(alloc_inst);

  for(int i = 0; i < 100; ++i)  //Insert data in the vector
     vA->push_back(i);

И затем, если клиентский процесс знает имена общих объектов ("values_A" и "values_B"), к ним легко получить доступ.

  managed_shared_memory segment(open_only, "MySharedMemory");
  MyVector *vA_client = segment.find<MyVector>("values_A").first;
  MyVector *vB_client = segment.find<MyVector>("values_B").first;

  //Use vector in reverse order
  std::sort(vA_client->rbegin(), vA_client->rend());

Но если клиент не знает названия этих объектов?

Как получить список этих объектов? {"values_A", "values_B"}.

Если бы было зарегистрировано несколько объектов другого типа ("MyVector2") (с именем "intA", "intB") - Как бы вы отфильтровали только те, чей тип MyVector?

У меня есть подозрение, что это связано с методами named_begin и named_end, но я не знаю, как его использовать.

Спасибо за помощь:)

1 ответ

Эти методы являются частью интерфейса диспетчера сегментов.

Остерегайтесь условий гонки, когда используете их напрямую. find_or_construct делает что-то еще, чем find а также construct последовательно в многопроцессной ситуации.

Пример:

Жить на Колиру

#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <iostream>
namespace bip = boost::interprocess;

using Shared = bip::managed_mapped_file;
using Manager = Shared::segment_manager;
template <typename T> using Alloc = bip::allocator<T, Manager>;
template <typename T> using V = boost::container::vector<T, Alloc<T> >;

int main() {
    bip::managed_mapped_file mmf(bip::open_or_create, "test.bin", 10ull<<10);
    auto* segment = mmf.get_segment_manager();

    for (auto it = segment->named_begin(); it != segment->named_end(); ++it) {
        std::cout << "before: " << std::string(it->name(), it->name_length()) << "\n";
    }

    for (auto next : { "foo", "bar", "qux" }) {
        if (!mmf.find<V<int> >(next).first)
        {
            mmf.find_or_construct<V<int> >(next)(segment);
            break;
        }
    }

    for (auto it = segment->named_begin(); it != segment->named_end(); ++it) {
        std::cout << "after:  " << std::string(it->name(), it->name_length()) << "\n";
    }
}

Печать (первый запуск):

after:  foo

Второй прогон:

before: foo
after:  bar
after:  foo

Третий прогон:

before: bar
before: foo
after:  bar
after:  foo
after:  qux

Четвертый (и более поздний) прогон:

before: bar
before: foo
before: qux
after:  bar
after:  foo
after:  qux
Другие вопросы по тегам