Как получить список именованных объектов в общей межпроцессорной памяти 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