如何在共享内存(C++)中存储stl对象
How to store stl objects in shared memory (C++)?
我有以下代码模式:
class A {
double a, b, c;
...
};
class B {
map<int, A> table; // Can have maximum of MAX_ROWS elements.
...
};
class C {
B entries;
queue<int> d;
queue<int> e;
...
};
现在我想把一个C类型的对象存储在一个共享内存中,这样不同的进程就可以附加、更新和读取它。我该怎么做?(注意:我知道如何在共享内存中存储一个固定大小的简单C数组。此外,请记住B.table可能有任意条目。
使用boost::interprocess,这个库公开了这个功能。
编辑:以下是您需要做的一些更改:
该示例已经定义了一个分配器,该分配器将从共享内存块进行分配,您需要将其传递给map
和queue
。这意味着你必须改变你的定义:
class B
{
map<int, A, less<int>, MapShmemAllocator> table;
// Constructor of the map needs the instance of the allocator
B(MapShmemAllocator& alloc) : table(less<int>(), alloc)
{ }
}
对于queue
,这有点复杂,因为它实际上只是一个适配器,所以您需要将真实的实现类作为模板参数传入:
typedef queue<int, deque<int, QueueShmemAllocator> > QueueType;
现在你的课程C
略有变化:
class C
{
B entries;
QueueType d, e;
C(MapShmemAllocator& allocM, QueueShmemAllocator& allocQ) : entries(allocM), d(allocQ), e(allocQ)
{ }
}
现在,从段管理器中,使用分配器构造C
的实例。
C *pC = segment.construct<C>("CInst")(allocM_inst, allocQ_inst);
我认为这应该奏效。注意:您需要提供两个分配器(一个用于queue
,一个用于map
),不确定是否可以从同一个段管理器构造两个分配器,但我不知道为什么不能。
在共享内存中构建和使用STL对象并不棘手(尤其是使用boost::interprocess包装器)。当然,您还应该使用同步机制(boost的named_mutex也没有问题)。
真正的挑战是在共享内存中保持STL对象的一致性。基本上,如果其中一个进程在一个糟糕的时间点崩溃,就会给其他进程留下两个大问题:
-
锁定的互斥(可以使用棘手的PID到互斥映射、健壮的互斥(只要可用)、定时互斥等来解决)
-
STL对象处于不一致状态(例如,擦除()过程中的半更新映射结构)。一般来说,这是不可恢复的,您需要从头开始销毁并重新构造共享内存区域中的对象(可能还会杀死所有其他进程)。你可以尝试拦截应用程序中所有可能的外部信号,并祈祷一切顺利,处理过程永远不会在糟糕的时刻失败。
在决定在系统中使用共享内存时,请记住这一点。
UPD:检查shmaps(https://github.com/rayrapetyan/shmaps)项目,以了解事情应该如何运作。
这可能很棘手。首先,您需要一个自定义分配器:BoostInterprocess有一个,我从它开始。在你的确切例子中,这可能已经足够了,但更一般地说,您需要确保所有子类型也使用共享内存。因此,如果您想从一个字符串,该字符串还需要一个自定义分配器,这意味着它的类型与std::string
不同,并且您不能复制或从std::string
分配给它(但您可以使用两个迭代器构造函数,例如:
typedef std::basic_string<char, std::char_traits<char>, ShmemAllocator> ShmemString;
std::map<ShmemString, X, std::less<ShmemString>, ShmemAllocator> shmemMap;
具有以下访问权限:
shmemMap[ShmemString(key.begin(), key.end())] ...
当然,你定义的进入地图的任何类型也必须使用任何分配的共享内存:Boost Interprocess具有CCD_ 10,这可能在这里有所帮助。
- 哪些存储了不完整类型的 STL 数据结构可以用作类成员?
- 如何复制存储在数组中的 STL 对象?
- 使用无序映射在STL中存储键值对
- 如何在 STL 容器中存储具有抽象模板类型的抽象模板化类?
- 如何使用 stl 容器有效地存储对象?(即根据其字段的值进行搜索)
- 如何删除在没有STL的队列中存储在数组中的第一个字符串元素
- 在C STL :: MAP内部节点中存储的内容
- 将 STL 映射存储到 Boost ConstBufferSequence 中
- 用于存储多种类型值的 STL 容器
- 将函子存储在 stl 映射中并调用它们
- 将指针存储在STL容器中,以供以后进行DealLocation
- 如何将模板对象存储在STL容器和成员功能调用中
- 保留存储在STL容器中的指针所指向的值(unordered_map)
- 如何在共享内存(C++)中存储stl对象
- 如何在C++中存储对 stl 容器元素的指针/迭代器引用
- 将值从STL矢量存储到另一个矢量
- 关于在 c++ 中将文件路径存储在集合 STL 中
- STL 按排序顺序存储数字
- 存储STL列表迭代器的指针安全吗?
- 如果使用 malloc 存储 STL 列表的分配内存,则运行时错误即将到来