简体   繁体   English

增加进程间共享内存的麻烦

[英]Boost interprocess shared memory trouble

I'm having using using Boost's interprocess for shared memory access. 我正在使用Boost的进程间进行共享内存访问。
What Im trying to do is store a map in shared memory and access if from across processes. 我想要做的是将地图存储在共享内存中,并从跨进程访问。 Below is the part of the code where I try to do the same -- 下面是我尝试做同样的代码的一部分 -

SharedMemoryManager.h 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

and SharedmemoryManager.cpp 和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
    }
}


The problem that I'm facing is that the first process that calls get_range_based_routing_code , thereby initializing the shared memory and populating the map, is able to retrieve the value from the map whereas any subsequent call to get_range_based_routing_code encounters a segmentation fault. 我面临的问题是调用get_range_based_routing_code的第一个进程,从而初始化共享内存并填充映射,能够从映射中检索值,而对get_range_based_routing_code任何后续调用get_range_based_routing_code遇到分段错误。
By adding cout statements, I have been able to infer that the below line is the one that causes the error(or is the lsat line of execution) -- 通过添加cout语句,我已经能够推断下面的行是导致错误的行(或者是lsat执行行) -

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

Im having trouble figuring this out and my inexperience in C++ is not helping. 我很难解决这个问题,而且我对C ++缺乏经验并没有帮助。 Any pointers ? 有什么指针吗?

You have to make the keytype allocate from the shared memory area too. 您还必须从共享内存区域进行keytype分配。

There are a number of Boost IPC samples that define a shared_string for this purpose. 有许多Boost IPC示例为此目的定义了shared_string You can re-use this. 你可以重复使用它。


The same goes for the std::string inside the ZipRangeInfo type. ZipRangeInfo类型中的std::string也是ZipRangeInfo Yes, this is a lot of work and troublesome. 是的,这是很多工作和麻烦。 In practice, you might want to replace ZipRangeInfo::code by some statically sized boost::array<char, ...> or char[N] 在实践中,您可能希望用一些静态大小的boost::array<char, ...>char[N]替换ZipRangeInfo::code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM