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

背景:

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

方案设计:

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

代码实现:

write端代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include
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_allocator;
typedef vector                     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, 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                            movable_to_map_value_type;
typedef allocator                    map_value_type_allocator;
typedef map< char_string, complex_data
           , std::less, map_value_type_allocator>          complex_map_type;

typedef map< char_string, complex_data
           , std::less, 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 type
   void_allocator alloc_inst (segment.get_segment_manager());
   //Construct the shared memory map and fill it
   complex_map_type *mymap = segment.construct
      //(object name), (first ctor parameter, second ctor parameter)
         ("MyMap")(std::less(), 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 
#include 
#include 
#include 
#include 
#include 
#include
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_allocator;
typedef vector                     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, 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                            movable_to_map_value_type;
typedef allocator                    map_value_type_allocator;
typedef map< char_string, complex_data
           , std::less, map_value_type_allocator>          complex_map_type;

typedef map< char_string, complex_data
           , std::less, 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("MyMap").first;
   complex_map_type_iter iter;

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

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

   return 0;
}

read运行结果如下:
基于boost的共享内存系列-map_第1张图片

参考资料:

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

你可能感兴趣的:(boost)