3

According to guide on Boost docs

It is possible to create named vectors of some type (for instance double)

  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);

And then if client process knows the names of shared objects ("values_A" and "values_B") it is easy to access them.

  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());

But if client doesn't know the names of those objects?

How to get list of those objects? {"values_A" , "values_B"}.

If there was some objects of other type ("MyVector2") registered (named "intA", "intB") - How would you filter only those, whose type is MyVector?

I have a suspicion that it has to do with method named_begin and named_end but I don't know how to use it.

Thank You for your help :)

user2614242
  • 177
  • 1
  • 2
  • 9

1 Answers1

2

These methods are part of the segment manager interface.

Beware of race conditions when using these directly. find_or_construct does something else than find and construct sequentially in a multi-process situation.

Example:

Live On Coliru

#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";
    }
}

Prints (first run):

after:  foo

Second run:

before: foo
after:  bar
after:  foo

Third run:

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

Fourth (and later) run:

before: bar
before: foo
before: qux
after:  bar
after:  foo
after:  qux
sehe
  • 374,641
  • 47
  • 450
  • 633