如何让boost_ordered_map在共享内存中工作

时间:2015-08-02 06:20:39

标签: boost shared-memory boost-interprocess

此程序通过执行

正确编译
g++ -o boostwrite boostwrite.cpp -lboost_system -lrt -lm -lpthread

版本为g ++(Ubuntu 4.9.2-0ubuntu1~14.04)4.9.2

设置unordered_map效果很好但是获取它的值不起作用 例如,在执行程序时

./boostwrite set


write valuebefore crash 1 

test1=0.1

write valuebefore crash 2 

test2=0.2

test1=0.1

write valuebefore crash 3 

test3=0.4

test2=0.2

test1=0.1

但是将地图的大小返回为零

/boostwrite get

mymap address 0x7fb1ca8ad118

reading value

reading valuebefore crash

reading valuebefore crash 0 

我在想这里有两个问题

  1. shared_memory_object ::除去( “MySharedMemory”);

  2. 否则if(strcmp(argv [1],“get”)== 0)     {               mymap = segment.construct(“MyHashMap”)//对象名称             (30,boost :: hash(),std :: equal_to()//

  3. 但我不知道如何解决问题?

    这里有任何助推专家帮忙吗?

    这个程序应该像
    一样工作  头文件  boostwrite.h

    #ifndef BOOSTWRITE_H
    #define BOOSTWRITE_H
       #include <boost/interprocess/managed_shared_memory.hpp>
        #include <boost/interprocess/allocators/allocator.hpp>
        #include <boost/interprocess/containers/string.hpp>
        #include <iostream>
        #include <boost/unordered_map.hpp>     //boost::unordered_map
        #include <functional>                  //std::equal_to
        #include <boost/functional/hash.hpp>   //boost::hash
    
    
    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<char, segment_manager_t>                           char_allocator;
    typedef basic_string<char, std::char_traits<char>, char_allocator>   char_string;
    typedef allocator<int, segment_manager_t>                            int_allocator;
    typedef allocator<float, segment_manager_t>                            float_allocator;
    typedef float complex_data;
    
    //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 allocator<map_value_type, segment_manager_t>                    map_value_type_allocator;
    typedef boost::unordered_map < char_string, complex_data
             , boost::hash<char_string >  ,std::equal_to<char_string >
             , map_value_type_allocator> complex_map_type2;
    
    complex_map_type2 * mymap;
    
    #endif
    

    boostwrite.cpp文件

    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/allocators/allocator.hpp>
    #include <boost/interprocess/containers/string.hpp>
    #include <iostream>
    #include <boost/unordered_map.hpp>     //boost::unordered_map
    #include <functional>                  //std::equal_to
    #include <boost/functional/hash.hpp>   //boost::hash
    #include "boostwrite.h"
    
    managed_shared_memory segment(open_or_create,"MySharedMemory", 65530);
    void_allocator alloc_inst (segment.get_segment_manager());
    bool insert(string str,float value);
    float readfloat(string str);
    int main (int argc ,char** argv)
    {
        shared_memory_object::remove("MySharedMemory");
    //  remove_shared_memory_on_destroy remove_on_destroy("MySharedMemory");
    
        if(strcmp(argv[1],"set")==0)
        {
    
            mymap = segment.construct<complex_map_type2>("MyHashMap")  //object name
            ( 30, boost::hash<char_string>(), std::equal_to<char_string>()                  //
            , segment.get_allocator<map_value_type>());                         //allocator instance
    
            insert("test1",0.1);
            insert("test2",0.2);
            insert("test3",0.4);
        }
    
        else if(strcmp(argv[1],"get")==0)
        {
              mymap = segment.construct<complex_map_type2>("MyHashMap")  //object name
                    ( 30, boost::hash<char_string>(), std::equal_to<char_string>()                  //
                    , segment.get_allocator<map_value_type>());  
            printf("mymap address %p \n",mymap);
    //      readfloat("test3");
        }
        return 0;
    }
    bool insert(string str,float value)
    {
        {
             char_string key_object(str.c_str(), alloc_inst);
             complex_data mapped_object(value);
             map_value_type value(key_object, mapped_object);
             mymap->insert(value);
        }
    
        printf("write valuebefore crash %ld \n",mymap->size());
        for(complex_map_type2::iterator i = mymap->begin(); i != mymap->end(); ++i){
            std::cout << i->first << "=" << i->second << std::endl;
          }
    
    }
    float readfloat(string str)
    {
        printf("reading value\n");
        typedef complex_map_type2::iterator iter;
        char_string key_object(str.c_str(), alloc_inst);
    
        printf("reading valuebefore crash\n");
        iter got = mymap->find(key_object);
        printf("reading valuebefore crash %ld \n",mymap->size());
    
    }
    

1 个答案:

答案 0 :(得分:1)

这里有两个主要问题:

  1. 在程序启动时始终删除共享内存文件
  2. &#34;获得&#34;该计划的一部分构建新地图
  3. 解决这些问题:

    1. 删除共享内存文件&#34; set&#34;在创建新的共享内存文件之前的程序的一部分(这还需要移动opennening或创建共享内存文件到&#34; set&#34;&#34; get&#34; parts)
    2. in&#34; get&#34;找到已创建的地图
    3. 您的代码已修复(您的代码有点乱 - 我没有费心去解决其他问题,比如不从需要返回的函数返回值等):

      // ......
      // #include's and other code
      // .....
      
      //managed_shared_memory segment(open_or_create,"MySharedMemory", 65530);
      //void_allocator alloc_inst (segment.get_segment_manager());
      bool insert(string str,float value, void_allocator &alloc_inst);
      float readfloat(string str, void_allocator &alloc_inst);
      int main (int argc ,char** argv)
      {
      try
      {
          //shared_memory_object::remove("MySharedMemory");
          //remove_shared_memory_on_destroy remove_on_destroy("MySharedMemory");
      
          if(strcmp(argv[1],"set")==0)
          {
      
              shared_memory_object::remove("MySharedMemory");
              managed_shared_memory segment(open_or_create,"MySharedMemory", 65530);
              void_allocator alloc_inst (segment.get_segment_manager());
              mymap = segment.construct<complex_map_type2>("MyHashMap")  //object name
              ( 30, boost::hash<char_string>(), std::equal_to<char_string>()                  //
              , segment.get_allocator<map_value_type>());                         //allocator instance
      
              insert("test1",0.1, alloc_inst);
              insert("test2",0.2, alloc_inst);
              insert("test3",0.4, alloc_inst);
          }
      
          else if(strcmp(argv[1],"get")==0)
          {
              managed_shared_memory segment(open_or_create,"MySharedMemory", 65530);
              void_allocator alloc_inst (segment.get_segment_manager());
              mymap = segment.find<complex_map_type2>("MyHashMap")  //object name
                       .first;
              printf("mymap address %p \n",mymap);
              readfloat("test3", alloc_inst);
          }
      }
      catch(boost::interprocess::interprocess_exception &e)
      {
          printf("%s\n", e.what());
      }
          return 0;
      }
      bool insert(string str,float value, void_allocator &alloc_inst)
      {
          {
               char_string key_object(str.c_str(), alloc_inst);
               complex_data mapped_object(value);
               map_value_type value(key_object, mapped_object);
               mymap->insert(value);
          }
      
          printf("write valuebefore crash %ld \n",mymap->size());
          for(complex_map_type2::iterator i = mymap->begin(); i != mymap->end(); ++i){
              std::cout << i->first << "=" << i->second << std::endl;
            }
      
      }
      float readfloat(string str, void_allocator &alloc_inst)
      {
          printf("reading value\n");
          typedef complex_map_type2::iterator iter;
          char_string key_object(str.c_str(), alloc_inst);
      
          printf("reading valuebefore crash\n");
          iter got = mymap->find(key_object);
          printf("reading valuebefore crash %ld \n",mymap->size());
          for(complex_map_type2::iterator i = mymap->begin(); i != mymap->end(); ++i){
              std::cout << i->first << "=" << i->second << std::endl;
          }
      }
      

      输出:

      ./boostwrite get
      mymap address 0x7f80a724d118 
      reading value
      reading valuebefore crash
      reading valuebefore crash 3 
      test3=0.4
      test2=0.2
      test1=0.1