20 Şubat 2018 Salı

interprocess vector Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/interprocess/containers/vector.hpp>
Tanımlama
Örnek
Şöyle yaparız.
namespace bip = boost::interprocess;

namespace Shared {
  using Segment         = bip::managed_mapped_file;
  using Manager         = Segment::segment_manager;
  template <typename T = void> //Allocator
  using Alloc       = bip::allocator<T, Manager>;
  template <typename T> //vector
  using Vector      = bip::vector<T, Alloc<T> >;
  
}
Örnek
Şöyle yaparız. Burada scoped_allocator_adaptor kullanılıyor. std::vector<string> gibi bir container'da container için kullanılan allocator, container içindeki nesneler tarafından da kullanılabilir anlamına geliyor.
namespace Shared {
  namespace bip = boost::interprocess;
  namespace bc  = boost::container;

  using Segment                     = bip::managed_shared_memory;
  using Manager                     = Segment::segment_manager;
  template <typename T>
  using Alloc = bc::scoped_allocator_adaptor<bip::allocator<T, Manager> >;
  template <typename T>
  using Vector= bip::vector<T, Alloc<T> >;
   
}
Elimizde şöyle bir kod olsun.
namespace Shared {

  template <typename Alloc = Alloc<void> > //Yukarıdaki allocator kullanılır
  struct Foo {
    using allocator_type = typename Alloc::template rebind<Foo>::other;
    using Ints = bip::vector<int, typename Alloc::template rebind<int>::other>;

    Foo(std::initializer_list<float> floats = {}, Ints data = {})
      : vectorData(std::move(data))
    {
      
    }

    template <typename OA, typename A>
    Foo(Foo<OA> const& other, A alloc = {}) 
      : vectorData(other.vectorData.begin(), other.vectorData.end(), alloc)
    {
      
    }

      Ints  vectorData;
    };

    template <typename A>
    std::ostream& operator<<(std::ostream& os, Foo<A> const& f) {
      os << "[";
      std::copy(std::begin(f.vectorData), std::end(f.vectorData),
        std::ostream_iterator<int>(std::cout, ";"));
      return os << "] }";
    }

}
Hem normal kullanımda hem de interprocess kullnım için şöyle yaparız.
using Foo       = Shared::Foo<std::allocator<void> >;
using InterFoo  = Shared::Foo<>;

using InterFoos = Shared::Vector<InterFoo>;
using Ints      = Shared::Vector<int>;

Constructor
Örnek
Elimizde bir struct ve onu içeren bir boost::interprocess::vector tanımı olsun.
struct Struct
{
  ...
};

using StructAllocator = boost::interprocess::allocator
    < Struct, boost::interprocess::managed_shared_memory::segment_manager >;

using StructVector = boost::interprocess::vector
    < Struct, Struct1Allocator>;
Şöyle yaparız.
boost::interprocess::managed_shared_memory segment = ...;
StructVector v (segment.get_segment_manager());
Örnek
managed_shared_memory tarafından kurulması için şöyle yaparız.
auto segment = Shared::open();
auto& inter_foos = *segment.find_or_construct<InterFoos>("InterFoos")
 (segment.get_segment_manager());
Destructor
İlginç bir şekilde vector yok olsa bile, managed_shared_memory belleği sınıfına belleğin artık kullanımladığını bildirmiyor. Yani heap gibi çalışmıyor.

emplace_back metodu
Şöyle yaparız.
// or copy from a non-shared vector:
std::vector<Foo> const local  = ...;

for (auto& local_foo : local)
  inter_foos.emplace_back(local_foo);
push_back metodu
Şöyle yaparız.
Struct element = ...;
v.push_back (element);

Hiç yorum yok:

Yorum Gönder