共享内存中分配的映射的映射

龙X

在的内部boost::interprocess::managed_shared_memory,我试图boost::unordered_map在另一个内部创建boost::unordered_map值,并std::string为两个映射创建共享内存段内的Map中的Map通过两个不同的进程访问,这些进程从外部和内部Map中获取值。

以下是我的实现,想知道这是否可行/正确或其他更好的方法?

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

    typedef std::string   KeyType;
    typedef std::string   ValueType;
    typedef std::pair<const KeyType, ValueType> MapType;
    typedef boost::interprocess::allocator<MapType, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
    typedef boost::unordered_map<KeyType, ValueType, boost::hash<KeyType>, std::equal_to<KeyType>, ShmemAllocator> InMap;
    ShmemAllocator alloc_inst(segment.get_segment_manager());
    InMap *inside_map = segment.construct<InMap>("SHM_IN_MAP")(3, boost::hash<KeyType>(), std::equal_to<KeyType>(), alloc_inst);


    typedef std::pair<const KeyType, MapType> MIMType;
    typedef boost::interprocess::allocator<MIMType, boost::interprocess::managed_shared_memory::segment_manager> MIMShmemAllocator;
    typedef boost::unordered_map<KeyType, MapType, boost::hash<KeyType>, std::equal_to<KeyType>, MIMShmemAllocator> OutMap;
    //MIMShmemAllocator alloc_inst(segment.get_segment_manager());   /*Commented due to Error*/
    OutMap *outside_map = segment.construct<OutMap>("SHM_OUT_MAP")(3, boost::hash<KeyType>(), std::equal_to<KeyType>(), alloc_inst);

其他详情:

CentOS 7上的gcc版本4.8.3 20140911(Red Hat 4.8.3-9)(GCC),BOOST_LIB_VERSION“ 1_58”

好的。

因此,存在一些基本错误,并且可能有些混乱。

接下来,有一些强大的技巧可以使嵌套容器与自定义(有状态)分配器配合使用更加方便。

这是工作示例中所有三个提示的汇总,有望对您有所帮助!


  1. 您的字符串也必须使用共享内存分配器

    否则,数据将在其他进程中非法使用。使用字符串将导致未定义的行为

    至少,使您的字符串使用共享内存分配器:

    namespace Shared {
        using Segment   = bip::managed_shared_memory;
    
        template <typename T>
        using Alloc     = bip::allocator<T, Segment::segment_manager>;
    
        using String    = boost::container::basic_string<char, std::char_traits<char>, Alloc<char> >;
        using KeyType   = String;
        using ValueType = String;
    }
    
  2. 映射分配器被过度指定。pair<K const, v>无论如何,包装映射中元素的实际节点类型都是实现定义的。那么地图如何知道如何分配这些节点?

    他们重新绑定分配器:请参见rebind此处的文档

    因此,您可以通过Alloc<void>或与相同的分配器Shared::String该地图将弄清楚:

    typedef boost::unordered_map<KeyType, ValueType, boost::hash<KeyType>, std::equal_to<KeyType>, Alloc<void> > InMap;
    typedef boost::unordered_map<KeyType, InMap,     boost::hash<KeyType>, std::equal_to<KeyType>, Alloc<void> > OutMap;
    
  3. 现在为电源提示

    将状态分配器传递给所有令人困惑的时间很烦人。它使代码一团糟。幸运的是,c ++ 11(和c ++ 03的Boost容器)涵盖了:

    • scoped_allocator_adaptor<T...>
    • allocator_type
    • uses_allocator<T> 特征

    这些助手可以使您的生活更加轻松。他们通过在适用时将分配器传递给元素类型构造函数来实现。自动地。同样,反弹分配器类型的隐式转换使事情正常进行。

    因此,实际上您可以使用正确的分配器(使其成为Scoped)和一个键来构造一个外部映射,并且从那里甚至不必继续指定分配器。

这是完整的演示:

Live On Coliru

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

namespace bip = boost::interprocess;

namespace Shared {
    using Segment = bip::managed_shared_memory;

    template <typename T>
    using Alloc   = bip::allocator<T, Segment::segment_manager>;
    using Scoped  = boost::container::scoped_allocator_adaptor<Alloc<char> >;

    using String  = boost::container::basic_string<char, std::char_traits<char>, Scoped>;
    using KeyType = String;

    typedef boost::unordered_map<KeyType, String, boost::hash<KeyType>, std::equal_to<KeyType>, Scoped> InMap;
    typedef boost::unordered_map<KeyType, InMap,  boost::hash<KeyType>, std::equal_to<KeyType>, Scoped> OutMap;
}

int main() {
    srand(time(NULL));

    Shared::Segment segment(bip::open_or_create, "BOOST_SHM", 65536);
    auto* mgr = segment.get_segment_manager();

    Shared::OutMap *p_outside_map = segment.find_or_construct<Shared::OutMap> ("SHM_OUT_MAP") (mgr);
    auto& outside_map = *p_outside_map;

    Shared::String sskey(mgr); // reduce shared allocations as they are costly (in terms of fragmentation/overhead)

    char outer_keys[3], inner_keys[3];
    std::generate_n(outer_keys, 3, [] { return rand()%26+'a'; });
    std::generate_n(inner_keys, 3, [] { return rand()%26+'a'; });

    for (auto key : outer_keys) {
        sskey = key;
        auto& inner = outside_map[sskey];

        for (auto more : inner_keys) {
            inner[sskey + "_" + more] += "value";
        }
    }

    for (auto const& oe : outside_map) {
        for (auto const& ie : oe.second) {
            std::cout << "outside_map[" << oe.first << "][" << ie.first << "] == " << ie.second << "\n";
        }
    }
}

实际上,要使其在Coliru上运行,我们需要使用映射文件:

Live On Coliru

运行几次:

outside_map[s][s_t] == value
outside_map[s][s_r] == value
outside_map[s][s_c] == value
outside_map[f][f_t] == value
outside_map[f][f_r] == value
outside_map[f][f_c] == value
outside_map[o][o_t] == value
outside_map[o][o_r] == value
outside_map[o][o_c] == value

第二轮:

outside_map[a][a_d] == value
outside_map[a][a_c] == value
outside_map[a][a_g] == value
outside_map[r][r_d] == value
outside_map[r][r_c] == value
outside_map[r][r_g] == value
outside_map[g][g_d] == value
outside_map[g][g_c] == value
outside_map[g][g_g] == value
outside_map[s][s_t] == value
outside_map[s][s_r] == value
outside_map[s][s_c] == value
outside_map[f][f_t] == value
outside_map[f][f_r] == value
outside_map[f][f_c] == value
outside_map[o][o_t] == value
outside_map[o][o_r] == value
outside_map[o][o_c] == value

请注意,每次运行如何成功地追加value到3个内部映射中的9个键上。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将已经分配的内存映射到共享内存

来自分类Dev

取消映射增强共享内存

来自分类Dev

取消映射增强共享内存

来自分类Dev

Linux中共享库的内存映射

来自分类Dev

在Linux中观察共享的映射文件内存

来自分类Dev

如何在DriverKit系统扩展中分配内存并将其映射到另一个进程?

来自分类Dev

共享内存段中映射数据的内存管理

来自分类Dev

使用内存映射在Android中跨进程共享内存

来自分类Dev

如何共享对内存映射文件的只读访问权限

来自分类Dev

使用std :: string键增强共享内存中的无序映射

来自分类Dev

Linux中共享库内存映射的访问权限

来自分类Dev

端口映射,内存映射

来自分类Dev

插入共享内存中的映射的映射时发生编译器错误

来自分类Dev

为什么在boost进程间共享内存中分配的对象占用的内存比所需的更多?

来自分类Dev

重复映射和取消映射单个页面时,mmap()无法分配内存

来自分类Dev

Windbg内存映射?

来自分类Dev

与&映射的可变内存位置

来自分类Dev

远程文件内存映射

来自分类Dev

Android进程内存映射

来自分类Dev

Python内存映射

来自分类Dev

弱映射内存泄漏

来自分类Dev

Windbg内存映射?

来自分类Dev

Linux内存映射文件

来自分类Dev

缓存到内存的映射

来自分类Dev

内存映射文件位置

来自分类Dev

Numpy 内存映射问题

来自分类Dev

理解内存映射

来自分类Dev

Windows中分配的内存的内容

来自分类Dev

C ++:在函数中分配内存