你永远不会检查指针 mymap 是否为空。
如果我们确定它存在,首先执行这个(一次):
// assuming this exists
Segment s(bip::open_or_create, "segment_name", 10 * 1024);
s.find_or_construct<MyShmMap>("segment_name")(s.get_segment_manager());
然后一切正常:Live On Coliru
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/unordered_map.hpp>
#include <boost/functional.hpp>
namespace bip = boost::interprocess;
namespace bc = boost::container;
using Segment = bip::managed_shared_memory;
using Mgr = Segment::segment_manager;
template <typename T> using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename K, typename V>
using UnorderedMap = boost::unordered_map<K, V, boost::hash<K>, //
std::equal_to<K>,
Alloc<std::pair<K const, V>>>;
using String = bc::basic_string<char, std::char_traits<char>, Alloc<char>>;
using MyShmMap = UnorderedMap<String, String>;
int main() {
{
// assuming this exists
Segment s(bip::open_or_create, "segment_name", 10 * 1024);
s.find_or_construct<MyShmMap>("segment_name")(s.get_segment_manager());
}
Segment segment(bip::open_read_only, "segment_name");
MyShmMap* mymap = segment.find<MyShmMap>("segment_name").first;
auto it = mymap->find(String("test", segment.get_segment_manager()));
if (it != mymap->end()) {
auto const& value = it->second;
}
}
我也借此机会
- 清理您的 type-def 以实现可重用性
- 请注意,在
.find 之后使用.at 非常浪费。这特别浪费,因为您使用 /shared/ 字符串作为键。
智能高效
您可以通过使用与字符串视图兼容的哈希/相等比较器以及使用advanced lookup:来真正提高性能:
template <typename K, typename V, typename Hash = boost::hash<K>,
typename EqCmp = std::equal_to<K>>
using UnorderedMap = boost::unordered_map<K, V, //
Hash, EqCmp, Alloc<std::pair<K const, V>>>;
using MyShmMap = UnorderedMap<String, String, boost::hash<std::string_view>, std::equal_to<void>>;
Live On Coliru
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/unordered_map.hpp>
#include <boost/functional.hpp>
namespace bip = boost::interprocess;
namespace bc = boost::container;
using Segment = bip::managed_shared_memory;
using Mgr = Segment::segment_manager;
template <typename T> using Alloc = bip::allocator<T, Segment::segment_manager>;
template <typename K, typename V, typename Hash = boost::hash<K>,
typename EqCmp = std::equal_to<K>>
using UnorderedMap = boost::unordered_map<K, V, //
Hash, EqCmp, Alloc<std::pair<K const, V>>>;
using String = bc::basic_string<char, std::char_traits<char>, Alloc<char>>;
using MyShmMap = UnorderedMap<String, String, boost::hash<std::string_view>, std::equal_to<void>>;
#include <string_view>
#include <iostream>
#include <iomanip>
int main()
{
{
// assuming this exists
Segment s(bip::open_or_create, "segment_name", 10 * 1024);
auto* m = s.get_segment_manager();
s.find_or_construct<MyShmMap>("segment_name")(m) //
->emplace(std::piecewise_construct, //
std::tuple("stuff", m), //
std::tuple("lives here", m));
}
Segment segment(bip::open_read_only, "segment_name");
MyShmMap* mymap = segment.find<MyShmMap>("segment_name").first;
auto hash = mymap->hash_function();
auto eq = mymap->key_eq();
if (auto it = mymap->find("stuff", hash, eq); it != mymap->end()) {
auto const& [k,v] = *it;
std::cout << std::quoted(k.c_str()) << " -> " << std::quoted(v.c_str()) << "\n";
}
}
打印出来的
"stuff" -> "lives here"
樱桃在上面
为了减少分配器的丑陋,例如:
Segment s(bip::open_or_create, "segment_name", 10 * 1024);
auto* m = s.get_segment_manager();
s.find_or_construct<MyShmMap>("segment_name")(m) //
->emplace(std::piecewise_construct, //
std::tuple("stuff", m), //
std::tuple("lives here", m));
考虑scoped allocators:
template <typename T> using Alloc = bc::scoped_allocator_adaptor< //
bip::allocator<T, Segment::segment_manager>>;
现在容器在使用分配器构造时传播分配器:
Segment s(bip::open_or_create, "segment_name", 10 * 1024);
auto& m = *s.find_or_construct<MyShmMap>("segment_name")(
s.get_segment_manager());
m.emplace("stuff", "lives here");
再次查看Live On Coliru。