1. 程式人生 > >用boost在共享記憶體上建立一個複雜的map

用boost在共享記憶體上建立一個複雜的map

boost的interprocess類提供了在共享記憶體上建立複雜資料物件和容器的方式,以下是在共享記憶體上建立一個string map的程式碼,程式碼在32位linux上測試通過
#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 <iostream>

using namespace boost::interprocess;

//型別和allocator的定義,使用共享記憶體時需要使用boost::interprocess中
//重新實現的容器而不能使用標準容器
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
{
  int               id_;
  char_string       char_string_;
  int_vector_vector int_vector_vector_;

public:
  //因為void_allocator能夠轉換為任何型別的allocator<T>, 所以我們能夠簡單的在建構函式中
  //使用void_allocator來初始化所有的內部容器
  complex_data(int id, const char *name, const void_allocator &void_alloc)
    : id_(id), char_string_(name, void_alloc), int_vector_vector_(void_alloc)
  {}
  ~complex_data(){}
};

//將map的key定義為一個string,而把map的value定義為一個complex_data物件
typedef std::pair<const char_string, complex_data>                      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;

int main ()
{
  //在程式開始和結束的時候移除同名的共享記憶體
  //如果只是讀其他程式建立的共享記憶體塊則不該包含remover
  struct shm_remove
  {
    shm_remove() { shared_memory_object::remove("MySharedMemory"); }
    ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
  } remover;
  //建立共享記憶體,根據測試,在32位的linux上,單塊命名的共享記憶體大小
  //最大為2^31-1,如果是讀其他程式建立的共享記憶體,則此句應寫為
  //managed_shared_memory segment(open_only, "MySharedMemory");
  managed_shared_memory segment(create_only,"MySharedMemory", 65536);

  //一個能夠轉換為任何allocator<T, segment_manager_t>型別的allocator 
  void_allocator alloc_inst (segment.get_segment_manager());

  //在共享記憶體上建立map
  //如果map已由其他程式建立,或者不確定map是否已建立,應如下:
  //complex_map_type *mymap = segment.find_or_construct<complex_map_type>
  complex_map_type *mymap = segment.construct<complex_map_type>
    ("MyMap")(std::less<char_string>(), alloc_inst);

  for(int i = 0; i < 100; ++i){
    //key(string) 和value(complex_data) 都需要在他們的建構函式中
	//包含一個allocator
	char tmp[16] = "";
	sprintf(tmp, "test%d", i);
    char_string  key_object(tmp, alloc_inst);
    complex_data mapped_object(i, "default_name", alloc_inst);
    map_value_type value(key_object, mapped_object);
    //向map中插值
    mymap->insert(value);
  }

  return 0;
}

此函式建立了一個map,其中key為string,value為一個複雜的結構,其中還包含了一個int vector

因為工程需要,只對boost參考文件中建立普通容器的容器做了實驗,更復雜的容器需參照boost文件進行

此程式使用boost版本為1.42.0

編譯時無需對boost進行單獨編譯,只需引用相應的(hpp)標頭檔案即可使用,編譯時需連線庫"-lrt",如果在64位系統上編譯,需要連線-lpthread