2014-05-01 28 views
0

我正在使用Boost的進程間共享內存訪問。
我試圖做的是將地圖存儲在共享內存中,如果來自跨進程則訪問。下面是我嘗試做相同的代碼部分 -
加速進程間共享內存故障

SharedMemoryManager.h

#ifndef SHARED_MEMORY_MANAGER_H 
#define SHARED_MEMORY_MANAGER_H 

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/containers/string.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/interprocess/sync/named_semaphore.hpp> 
#include <boost/interprocess/containers/map.hpp> 

enum RangeBound { START, END, SINGLE }; 

typedef struct { 
    std::string code; 
    RangeBound flag; 
} ZipRangeInfo; 

typedef std::string RangeKeyType; 
typedef std::pair<const RangeKeyType, ZipRangeInfo> RangeValueType; 

typedef boost::interprocess::allocator<RangeValueType, boost::interprocess::managed_shared_memory::segment_manager> RangeBasedShmemAllocator; 

typedef boost::interprocess::map<RangeKeyType, ZipRangeInfo, std::less<RangeKeyType>, RangeBasedShmemAllocator> SharedRangeBasedMap; 

class SharedMemoryManager { 

private: 
    static boost::interprocess::managed_shared_memory *segment; 
    static RangeBasedShmemAllocator *alloc_range_map; 
public: 
    static char* get_range_based_routing_code(char *dataItem, char *fileName); 
    static SharedRangeBasedMap* get_range_based_routing_table(char *fileName); 
    static void load_range_based_routing_table(const char *fileName); 
}; 

#endif //SHARED_MEMORY_MANAGER_H 

和 SharedmemoryManager.cpp

#include "SharedMemoryManager.h" 

const std::string shm_code_util("SharedMemoryUtil"); 

//Initializing shared memory of size 1 GB. 
boost::interprocess::managed_shared_memory *SharedMemoryManager::segment = 
     new boost::interprocess::managed_shared_memory(
       boost::interprocess::open_or_create, "CRS", 1024 * 1024 * 1024); 
RangeBasedShmemAllocator *SharedMemoryManager::alloc_range_map = 
     new RangeBasedShmemAllocator(segment->get_segment_manager()); 

// Method definitions 

char* SharedMemoryManager::get_range_based_routing_code(char *dataItem, 
     char *fileName) { 

    char* result = NULL; 
    // Postal Code Scrubbing Logic 
    if (dataItem == NULL) 
     return NULL; 
    try { 
     char *dataIt = (char *) calloc(strlen(dataItem) + 1, sizeof(char)); 
     strcpy(dataIt, dataItem); 

     SharedRangeBasedMap *routing_table = get_range_based_routing_table(
       fileName); 
     std::cout << "Hash Table Size :" << routing_table->size(); 
     if (routing_table != NULL && routing_table->size() > 0) { 
      RangeKeyType key(dataItem); 
      SharedRangeBasedMap::const_iterator routing_entry = 
        routing_table->lower_bound(key); 
      std::cout << "Got iterator"; 
      if (routing_entry == routing_table->end()) { 
       return NULL; 
      } 
      if (routing_entry->first == key 
        || routing_entry->second.flag == END) { 
       result = (char *) routing_entry->second.code.c_str(); 
      } 
     } 
     free(dataIt); 

     return result; 
    } catch (std::exception &e) { 
     throw; 
    } 
} 

SharedRangeBasedMap* SharedMemoryManager::get_range_based_routing_table(
     char *fileName) { 

    boost::interprocess::named_semaphore sync_semaphore(
      boost::interprocess::open_or_create, "LoadFilesSemaphore", 1); 
    sync_semaphore.wait(); 
    try { 
     SharedRangeBasedMap *routing_table = segment->find_or_construct< 
       SharedRangeBasedMap>(fileName)(std::less<RangeKeyType>(), 
         *alloc_range_map); 
     if (routing_table->size() == 0) { 
      load_range_based_routing_table(fileName); 
     } 
     sync_semaphore.post(); 

     return routing_table; 
    } catch (...) { 
     std::cout << "An exception was thrown; couldn't load post codes."; 
     sync_semaphore.post(); 
     return NULL; 
    } 
    return NULL; 
} 

void SharedMemoryManager::load_range_based_routing_table(const char *fileName) { 

    SharedRangeBasedMap *range_based_map = NULL; 
    range_based_map = segment->find_or_construct<SharedRangeBasedMap>(
       fileName)(std::less<RangeKeyType>(), *alloc_range_map); 


    // Build the hash if empty 
    if (range_based_map != NULL && range_based_map->size() == 0) { 
     //logic to populate the map - tested to work correctly 
    } 
} 


說我的問題面向的是第一個調用get_range_based_routing_code的進程,從而初始化共享內存並填充地圖,能夠從地圖中檢索值,而對的任何後續調用遇到分段錯誤。
通過添加cout語句,我已經能夠推斷下面行是導致錯誤的一個(或是執行的LSAT線) -

SharedRangeBasedMap::const_iterator routing_entry = 
        routing_table->lower_bound(key); 

林具有麻煩搞清楚了這一點,並我在C++方面的缺乏經驗並沒有幫助。任何指針?

+0

'int count = 0;如果(count> 0){...'條件從未滿足。你的_real_代碼是什麼?此外,它似乎要好得多移動SharedMemoryManager的'互斥下的初始化:: segment'以及(哦,對了,而不是使用一個命名信號量(1),因爲這是更簡單/更清晰。一個名爲互斥) – sehe

+0

我剝了下來load_range_based_routing_table,因爲它的測試工作正常,也因爲它有很多業務邏輯。我已對load_range_based_routing_table進行了更改以消除上述疏忽。 – ping

回答

2

您還必須從共享內存區域分配keytype。

有許多,爲了這個目的定義shared_string升壓IPC樣品。你可以重新使用它。


這同樣適用於在​​型內std::string。是的,這是很多工作和麻煩。在實踐中,您可能想用一些靜態大小替換ZipRangeInfo::codechar[N]

+0

使共享內存中的Keytype分配工作。 Upvoting和Accepting。謝謝! – ping