字符串共享内存映射的向量

Vector of string shared memory map

本文关键字:向量 映射 内存 共享 字符串      更新时间:2023-10-16

如何将字符串附加到map中包含的向量?结构是映射(浮点数,向量(字符串((,其中映射处于共享状态 memory.my 问题是如果键==所需的键,然后将字符串附加到字符串向量?

你的意思是这样的:

#include <map>
#include <vector>
#include <string>
#include <iostream>
int main()
{
std::map<float, std::vector<std::string>> m;
m[.5f].emplace_back("First");
m[.5f].emplace_back("Second");
m[.0f].emplace_back("Hello");
m[.0f].emplace_back("World");
for(const auto& [key, value] : m)
{
std::cout << "Key: " << key << 'n';
for(const auto& str : value)
std::cout << 't' << str << 'n';
}
std::cout.flush();
return 0;
}

实际上,在共享内存中执行此操作非常困难。

如果你把所有的分配器都弄对了,并添加了锁定,你通常会得到非常笨拙的代码,由于所有的分配器都在传递,所以很难阅读。

但是,您可以使用Boost的范围分配器适配器,它将做很多(很多(魔法,使生活更美好。

我认为下面的代码示例几乎可以确定最佳位置。

警告:这是建立在多年试图将其击败以屈服的经验之上的。如果你只是在"魔术"的边界之外(主要是由于uses_allocator<>scoped_allocator_adaptor而提供的就地构造支持(,你会发现它崩溃了,你将编写大量的手动构造函数/转换调用来使其工作。

住在科里鲁

#define DEMO
#include <iostream>
#include <iomanip>
#include <mutex>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/managed_mapped_file.hpp> // For Coliru (doesn't support shared memory)
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/container/scoped_allocator.hpp>
namespace bip = boost::interprocess;
namespace bc = boost::container;
namespace Shared {
using Segment = bip::managed_mapped_file; // Coliru doesn't support bip::managed_shared_memory
template <typename T> using Alloc = bc::scoped_allocator_adaptor<bip::allocator<T, Segment::segment_manager> >;
template <typename V>
using Vector = bip::vector<V, Alloc<V> >;
template <typename K, typename V, typename Cmp = std::less<K> >
using Map = bip::map<K, V, Cmp, Alloc<std::pair<K const, V> > >;
using String = bip::basic_string<char, std::char_traits<char>, Alloc<char> >;
using Mutex = bip::interprocess_mutex;
}
namespace Lib {
using namespace Shared;
struct Data {
using Map = Shared::Map<float, Shared::Vector<Shared::String> >;
mutable Mutex _mx;
Map _map;
template <typename Alloc> Data(Alloc alloc = {}) : _map(alloc) {}
bool append(float f, std::string s) {
std::lock_guard<Mutex> lk(_mx); // lock
auto it = _map.find(f);
bool const exists = it != _map.end();
#ifndef DEMO
if (exists) {
it->second.emplace_back(s);
}
#else
// you didn't specify this, but lets insert new keys here, if
// only for the demo
_map[f].emplace_back(s);
#endif
return exists;
}
size_t size() const {
std::lock_guard<Mutex> lk(_mx); // lock
return _map.size();
}
friend std::ostream& operator<<(std::ostream& os, Data const& data) {
std::lock_guard<Mutex> lk(data._mx); // lock
for (auto& [f,v] : data._map) {
os << f << " ->";
for (auto& ss : v) {
os << " " << std::quoted(std::string(ss));
}
os << "n";
}
return os;
}
};
}
struct Program {
Shared::Segment msm { bip::open_or_create, "data.bin", 10*1024 };
Lib::Data& _data = *msm.find_or_construct<Lib::Data>("data")(msm.get_segment_manager());
void report() const {
std::cout << "Map contains " << _data.size() << " entriesn" << _data;
}
};
struct Client : Program {
void run(float f) {
_data.append(f, "one");
_data.append(f, "two");
}
};
int main() {
{
Program server;
server.report();
Client().run(.5f);
Client().run(.6f);
}
// report again
Program().report();
}

首次运行将打印:

Map contains 0 entries
Map contains 2 entries
0.5 -> "one" "two"
0.6 -> "one" "two"

第二次运行:

Map contains 2 entries
0.5 -> "one" "two"
0.6 -> "one" "two"
Map contains 2 entries
0.5 -> "one" "two" "one" "two"
0.6 -> "one" "two" "one" "two"