分配器很好(魔法在offset_ptr 中,并且跨进程边界是透明的)。
如果“客户端”破坏了字符串,那么您正在做的不是阅读。您很可能会收到一份副本,例如:
auto by_copy = smap.find(key)->second; // makes a copy
试试,例如去做
auto const& by_ref = smap.find(key)->second; // doesn't copy
或者,您可能正在执行smap[key],如果密钥不存在,它会自动分配。这可能会导致老式的竞争条件(在进程之间共享数据很像在线程之间共享数据:您需要适当的同步)。
最后,你没有提到 /anything/ 关于密钥,但如果它也是一个字符串,那么只有按密钥查找很容易从共享内存中分配(而且,它是一个临时的,它会破坏)。比赛条件再次迫在眉睫。另见want to efficiently overcome mismatch between key types in a map in Boost.Interprocess shared memory
演示
如果没有合适的SSCCE 或MCVE,让我向你扔一个。您可能会发现自己的做法有所不同。
#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
namespace bip = boost::interprocess;
namespace shared {
namespace bc = boost::container;
using Segment = bip::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T>
using Alloc = bc::scoped_allocator_adaptor<bip::allocator<T, Manager> >;
using String = bip::basic_string<char, std::char_traits<char>, Alloc<char> >;
template <typename K, typename V, typename Cmp = std::less<K> >
using Map = bip::map<K, V, Cmp, Alloc<std::pair<K const, V> > >;
};
int main() {
using namespace shared;
Segment smt(bip::open_or_create, "de06c60a-0b80-4b20-a805-b3f405f35427", 20ul<<20); // 20 mb
auto& mat = *smt.find_or_construct<Map<String, String> >("dict")(smt.get_segment_manager());
if (mat.empty()) {
mat.emplace("1", "one");
mat.emplace("2", "two");
mat.emplace("3", "three");
} else {
// shared string factory
auto ss = [&](auto... stuff) { return String(stuff..., smt.get_segment_manager()); };
auto copy = mat.at(ss("3")); // constructs and destructs temp String("3"); constructs copy
auto& ref = mat.at(ss("2")); // constructs and destructs temp String("2"); no copy
std::cout << "copy: " << copy << "\n";
std::cout << "ref: " << ref << "\n";
// iterate with no shared temps or copies:
for (auto& p : mat)
std::cout << "entry '" << p.first << "' -> '" << p.second << "'\n";
} // destructs copy
}
在 Coliru 上也是如此,但使用内存映射文件(因为那里不允许共享内存):
Live On Coliru
using Segment = bip::managed_mapped_file;
第一次运行不打印,后续运行:
copy: three
ref: two
entry '1' -> 'one'
entry '2' -> 'two'
entry '3' -> 'three'