2016-04-25 11 views
1

Dies ist mein Code:unordered_map mit String in managed_shared_memory nicht

int main (int argc, char *argv[]) 
{ 
    typedef int KeyType; 
    typedef string MappedType; 

    typedef std::pair<KeyType, MappedType> ValueType; 
    typedef boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager> ShmAlloc; 
    typedef boost::unordered_map<KeyType, MappedType, boost::hash<KeyType>, std::equal_to<KeyType>, ShmAlloc> ShmHashMap; 

    boost::interprocess::managed_shared_memory segment(boost::interprocess::open_or_create, "ContainerSharedMemory", 65536); 

    if(argc == 2 && string(argv[1]) == "clear") 
    { 
     boost::interprocess::shared_memory_object::remove("ContainerSharedMemory"); 
     return 0; 
    } 

    ShmHashMap *hash_map = segment.find_or_construct<ShmHashMap>(boost::interprocess::unique_instance)(segment.get_segment_manager()); 

    if(hash_map == NULL) 
    { 
     cout << "find_or_construct error" << endl; 
     return 0; 
    } 

    for(int i = 0; i < 5; ++i) { 
     ShmHashMap::iterator iter = hash_map->find(i); 
     if (iter == hash_map->end()) { 
      hash_map->insert(ValueType(i, "test")); 
     } 
    } 

    cout << "all..." << endl; 
    for(ShmHashMap::iterator iter = hash_map->begin(); iter != hash_map->end(); ++iter) 
    { 
     cout << iter->first << "|" << iter->second << endl; 
    } 
    cout << "end..." << endl; 

    return 0; 
} 

alles in Ordnung ist, wenn MappedType int, sondern ein Segment Fehler Whit dieser Code wie folgt aus: enter image description here

Rerun dieses Programm für den Zugriff Hash-Karte im Shared Memory wird coredump

---------------------------- erneut bearbeiten --------- -------------------------

das Problem über string ist gelöst von sehe, danke und wenn ich eine Template-Klasse entwerfe das Detail zu verbergen, wie könnte ich tun? wenn es einen perfekten Weg gibt

template<typename MappedType> 
struct ComplexMappedType 
{ 
    ComplexMappedType(): t_access(0), t_expire(0) {} 
    ComplexMappedType(const MappedType& v, uint32_t a, uint32_t e): value(v), t_access(a), t_expire(e) {} 
    MappedType value; 
    uint32_t t_access; 
    uint32_t t_expire; 
}; 

template <typename KeyType, typename MappedType> 
class MMSHashMap 
{ 
private: 
    typedef ComplexMappedType<MappedType> DataType; 
    typedef std::pair<KeyType, DataType> ValueType; 
    typedef boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager> ShmAlloc; 
    typedef boost::unordered_map<KeyType, DataType, boost::hash<KeyType>, std::equal_to<KeyType>, ShmAlloc> ShmHashMap; 

public: 
    MMSHashMap(const std::string& name, size_t size, float e_thr, float e_scale); 
    ~MMSHashMap() {delete pMemorySegment;} 

    size_t getMEMSize() { return pMemorySegment->get_size(); } 
    size_t getMEMFreeSize() { return pMemorySegment->get_free_memory(); } 

    bool get(const KeyType& key, MappedType& value, uint32_t& expire); 
    bool set(const KeyType& key, const MappedType& value, uint32_t expire); 
    bool del(const KeyType& key); 

private: 
    void doCapacityElimination(); 

    std::string _name; 
    boost::interprocess::managed_shared_memory* pMemorySegment; 
    boost::shared_mutex mutex, mutex_eliminate; 
    float fEliminateThreshold, fEliminateScale; 
}; 
+0

Wenn Sie eine neue Frage haben, eine neue Frage stellen. Es wäre wahrscheinlich ein Duplikat von dem, das ich verlinkt habe [http://stackoverflow.com/questions/28608185/boostinterprocess-scoped-allocator-and-containers-of-containers-not-in-shared/28664248#28664248) – sehe

+0

ok, ich lese Ihnen Antwort in diesem Link zuerst ... danke ~ –

Antwort

2

Natürlich. std::string wird vom Heap zugewiesen.

Der Heap befindet sich in Ihrem Prozessadressraum, daher wird jeder andere Prozess, der den gleichen Shared Memory liest, einen falschen RAW-Zeiger erhalten und UB aufrufen.

Sie müssen einen Shared-Memory-Allokator mit den Zeichenfolgen auch verwenden.

Live On Coliru (mapped-Datei für Coliru verwenden)

Mit Shared Memory:

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/container/scoped_allocator.hpp> 
#include <boost/container/string.hpp> 
#include <boost/unordered_map.hpp> 
#include <iostream> 

namespace bip = boost::interprocess; 

int main (int argc, char *argv[]) 
{ 
    typedef int KeyType; 

    typedef boost::container::basic_string<char, std::char_traits<char>, bip::allocator<char, bip::managed_shared_memory::segment_manager> > MappedType; 

    typedef std::pair<KeyType, MappedType> ValueType; 
    typedef boost::interprocess::allocator<ValueType, boost::interprocess::managed_shared_memory::segment_manager> ShmAlloc; 
    typedef boost::unordered_map<KeyType, MappedType, boost::hash<KeyType>, std::equal_to<KeyType>, boost::container::scoped_allocator_adaptor<ShmAlloc> > ShmHashMap; 

    boost::interprocess::managed_shared_memory segment(boost::interprocess::open_or_create, "ContainerSharedMemory", 65536); 

    if(argc == 2 && std::string(argv[1]) == "clear") 
    { 
     boost::interprocess::shared_memory_object::remove("ContainerSharedMemory"); 
     return 0; 
    } 

    ShmHashMap *hash_map = segment.find_or_construct<ShmHashMap>(boost::interprocess::unique_instance)(segment.get_segment_manager()); 

    if(hash_map == NULL) 
    { 
     std::cout << "find_or_construct error" << std::endl; 
     return 0; 
    } 

    for(int i = 0; i < 5; ++i) { 
     ShmHashMap::iterator iter = hash_map->find(i); 
     if (iter == hash_map->end()) { 
      hash_map->insert(ValueType(i, MappedType { "hello", segment.get_segment_manager() })); 
     } 
    } 

    std::cout << "all..." << std::endl; 
    for(ShmHashMap::iterator iter = hash_map->begin(); iter != hash_map->end(); ++iter) 
    { 
     std::cout << iter->first << "|" << iter->second << std::endl; 
    } 
    std::cout << "end..." << std::endl; 
} 

Drucke

all... 
4|hello 
3|hello 
2|hello 
1|hello 
0|hello 
end... 
+0

Wie kann ich einen Zuordner zuweisen, zeigen Sie mir einige Details, danke –

+0

Woof Woof. Manche Leute haben Aufgaben zu erledigen. Sorry für die Verzögerung (PS. Ich habe viele Antworten, die genau diese Dinge bereits auf der Website showing, Sie könnten durch die Suche geholfen haben) – sehe

+0

kann Code nicht einfügen ... wenn ich eine Vorlage Klasse wie folgt einkapseln: Vorlage Klasse MMSHashMap .... wie kann ich es so gestalten, dass das Zuordnungsdetail ausgeblendet wird –

Verwandte Themen