Как заставить boost_ordered_map работать в разделяемой памяти

Эта программа, приведенная ниже, правильно компилируется, выполняя

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 

я думаю тут 2 проблемы

  1. shared_memory_object::remove("MySharedMemory");

  2. else if(strcmp(argv[1],"get")==0) { mymap = segment.construct("MyHashMap") // имя объекта ( 30, boost::hash(), std::equal_to() / /

Но я не знаю, как решить проблему?

Есть тут специалисты по бустингу, которые помогут?

Эта программа должна работать как
Заголовочный файл 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());

}

person Sri Kant    schedule 02.08.2015    source источник


Ответы (1)


Здесь есть 2 основные проблемы:

  1. файл общей памяти всегда удаляется при запуске программы
  2. "получить" часть программы создает новую карту

Для решения этих проблем:

  1. удалите файл общей памяти в части «установить» программы непосредственно перед созданием нового файла общей памяти (это также потребует перемещения открытия или создания файла общей памяти в части «установить» и «получить»)
  2. в "get" найти уже созданную карту

Ваш код исправлен (ваш код немного беспорядок - я не удосужился исправить другие проблемы, такие как невозврат значений из функций, требующих возврата, и т. д.):

// ......
// #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
person doqtor    schedule 02.08.2015