基于boost的共享内存系列-map

背景:

将自定义的map类型以共享内存的方式进行保留,以进行进程间通信。

方案设计:

map是容器的一种,而如果其key或者value也是容器的话,则该问题可以视为容器中的容器问题。如果在容器中又包含了容器的话,那么每个容器都是需要一个allocator。为避免使用数个复杂定义的分配器,我们可以使用空分配器提供的类型擦除和隐式转换空分配器至其他类型的能力。
实现过程:
创建共享内存片段managed_shared_memory::segment_manager;
为共享内存片段创建分配器,这是为了在堆内存中分配空间。如果整个map中不涉及到堆空间的操作,而是仅仅用到int,char[]等(不涉及new操作)在栈空间的数据话,是无需采用分配器的。

代码实现:

write端代码:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/lexical_cast.hpp>
#include<iostream>
using namespace boost::interprocess;

//Typedefs of allocators and containers
typedef managed_shared_memory::segment_manager                       segment_manager_t;
typedef allocator<void, segment_manager_t>                           void_allocator;
typedef allocator<int, segment_manager_t>                            int_allocator;
typedef vector<int, int_allocator>                                   int_vector;
typedef allocator<int_vector, segment_manager_t>                     int_vector_allocator;
typedef vector<int_vector, int_vector_allocator>                     int_vector_vector;
typedef allocator<char, segment_manager_t>                           char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>   char_string;

class complex_data
{
   public:
       int               id_;
       char_string       char_string_;
       int_vector_vector int_vector_vector_;

   public:
   //Since void_allocator is convertible to any other allocator<T>, we can simplify
   //the initialization taking just one allocator for all inner containers.
   complex_data(int id, const char *name, const void_allocator &void_alloc)
      : id_(id), char_string_(name, void_alloc), int_vector_vector_(void_alloc)
   {}
   //Other members...
};

//Definition of the map holding a string as key and complex_data as mapped type
typedef std::pair<const char_string, complex_data>                      map_value_type;
typedef std::pair<char_string, complex_data>                            movable_to_map_value_type;
typedef allocator<map_value_type, segment_manager_t>                    map_value_type_allocator;
typedef map< char_string, complex_data
           , std::less<char_string>, map_value_type_allocator>          complex_map_type;

typedef map< char_string, complex_data
           , std::less<char_string>, map_value_type_allocator>::iterator complex_map_type_iter;

int main ()
{
   //Remove shared memory on construction and destruction
//   struct shm_remove
//   {
//      shm_remove() { shared_memory_object::remove("MySharedMemory"); }
//      ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
//   } remover;
//根据具体情况确实是否需要对内存数据进行remove操作。本文的写进程和读进程是分开的,所以保留缓存中的数据。

//   //Create shared memory
   managed_shared_memory segment(create_only,"MySharedMemory",65536);


   //write------begin-----------
   //An allocator convertible to any allocator<T, segment_manager_t> type
   void_allocator alloc_inst (segment.get_segment_manager());
   //Construct the shared memory map and fill it
   complex_map_type *mymap = segment.construct<complex_map_type>
      //(object name), (first ctor parameter, second ctor parameter)
         ("MyMap")(std::less<char_string>(), alloc_inst);

   for(int i = 0; i < 50; ++i)
   {
      //Both key(string) and value(complex_data) need an allocator in their constructors
      char_string  key_object(alloc_inst);
      std::string temp = "key" + boost::lexical_cast< std::string >(i);
      key_object=temp.c_str();
      temp = "default_name_" + boost::lexical_cast<std::string>(i);
      complex_data mapped_object(i, temp.c_str(), alloc_inst);
      map_value_type value(key_object, mapped_object);
      //Modify values and insert them in the map
      mymap->insert(value);
   }
   //write------end-----------
   return 0;
}

在read的时候注意迭代器的使用。
read端代码:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/lexical_cast.hpp>
#include<iostream>
using namespace boost::interprocess;

//Typedefs of allocators and containers
typedef managed_shared_memory::segment_manager                       segment_manager_t;
typedef allocator<void, segment_manager_t>                           void_allocator;
typedef allocator<int, segment_manager_t>                            int_allocator;
typedef vector<int, int_allocator>                                   int_vector;
typedef allocator<int_vector, segment_manager_t>                     int_vector_allocator;
typedef vector<int_vector, int_vector_allocator>                     int_vector_vector;
typedef allocator<char, segment_manager_t>                           char_allocator;
typedef basic_string<char, std::char_traits<char>, char_allocator>   char_string;

class complex_data
{
   public:
       int               id_;
       char_string       char_string_;
       int_vector_vector int_vector_vector_;

   public:
   //Since void_allocator is convertible to any other allocator<T>, we can simplify
   //the initialization taking just one allocator for all inner containers.
   complex_data(int id, const char *name, const void_allocator &void_alloc)
      : id_(id), char_string_(name, void_alloc), int_vector_vector_(void_alloc)
   {}
   //Other members...
};

//Definition of the map holding a string as key and complex_data as mapped type
typedef std::pair<const char_string, complex_data>                      map_value_type;
typedef std::pair<char_string, complex_data>                            movable_to_map_value_type;
typedef allocator<map_value_type, segment_manager_t>                    map_value_type_allocator;
typedef map< char_string, complex_data
           , std::less<char_string>, map_value_type_allocator>          complex_map_type;

typedef map< char_string, complex_data
           , std::less<char_string>, map_value_type_allocator>::iterator complex_map_type_iter;

int main ()
{
   //read------begin------
   //Find the vector using the c-string name
   managed_shared_memory segment(open_only,"MySharedMemory");
   complex_map_type *myvector = segment.find<complex_map_type>("MyMap").first;
   complex_map_type_iter iter;

   //print the result
   std::cout<<"size of map="<<myvector->size()<<std::endl;

   for (iter = myvector->begin(); iter != myvector->end(); ++iter)
   {
       std::cout <<"key:"<< iter->first <<std::endl;
       std::cout<<"value:"<<iter->second.id_<<","<<iter->second.char_string_<<std::endl;
   }
   //write------end-------

   return 0;
}

read运行结果如下:
这里写图片描述

参考资料:

http://www.boost.org/doc/libs/1_49_0/doc/html/interprocess/allocators_containers.html

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值