C++ Boost进程间:托管共享内存错误
我正在使用boosts进程间库在多个程序之间共享内存。3或4个其他程序将按客户顺序读取和写入共享内存内容。对内存空间的访问需要序列化 在下面的示例程序中,引擎在risk_队列的内容上循环,如果已填充,则获取第一个客户订单号并定位该订单以进行处理C++ Boost进程间:托管共享内存错误,c++,memory,boost,C++,Memory,Boost,我正在使用boosts进程间库在多个程序之间共享内存。3或4个其他程序将按客户顺序读取和写入共享内存内容。对内存空间的访问需要序列化 在下面的示例程序中,引擎在risk_队列的内容上循环,如果已填充,则获取第一个客户订单号并定位该订单以进行处理 在每个程序使用的objects.h头文件中: struct cust_order { int ID; char CLID[128]; int CUST_ID; char ORDER_STATUS; }; cust_order o;
- 在每个程序使用的objects.h头文件中:
结构客户订单{ int-ID; char-CLID[128]; 国际客户识别码; 字符顺序状态; }; 客户订单; boost::进程间::托管共享内存 客户订单(boost::进程间::打开或创建“客户订单”, 65536 * 100); typedef int cust_order_KeyType; 类型定义客户订单客户订单映射类型; typedef std::对客户订单值类型; typedef boost::进程间::分配器< 客户订单价值类型, boost::进程间::托管的共享内存::段管理器> 客户订单分配器; typedef boost::进程间::映射 客户订单地图; cust_order_MySHMMap::迭代器cust_order_iter; boost::进程间::托管共享内存 风险队列段(boost::进程间::打开或创建“风险队列”, 65536 * 100); typedef int risk_queue_keype; typedef int risk_queue_MappedType; typedef std::配对风险\队列\值类型; typedef boost::进程间::分配器< 风险\队列\值类型, boost::进程间::托管的共享内存::段管理器> 风险队列分配器; typedef boost::进程间::映射 风险队列地图; 风险队列:迭代器风险队列;struct cust_order { int ID; char CLID[128]; int CUST_ID; char ORDER_STATUS; }; cust_order o; boost::interprocess::managed_shared_memory cust_order_segment(boost::interprocess::open_or_create, "cust_order", 65536 * 100); typedef int cust_order_KeyType; typedef cust_order cust_order_MappedType; typedef std::pair<const int, cust_order> cust_order_ValueType; typedef boost::interprocess::allocator< cust_order_ValueType, boost::interprocess::managed_shared_memory::segment_manager> cust_order_ShmemAllocator; typedef boost::interprocess::map<cust_order_KeyType, cust_order_MappedType, std::less<cust_order_KeyType>, cust_order_ShmemAllocator> cust_order_MySHMMap; cust_order_MySHMMap::iterator cust_order_iter; boost::interprocess::managed_shared_memory risk_queue_segment(boost::interprocess::open_or_create, "risk_queue", 65536 * 100); typedef int risk_queue_KeyType; typedef int risk_queue_MappedType; typedef std::pair<const int, int> risk_queue_ValueType; typedef boost::interprocess::allocator< risk_queue_ValueType, boost::interprocess::managed_shared_memory::segment_manager> risk_queue_ShmemAllocator; typedef boost::interprocess::map<risk_queue_KeyType, risk_queue_MappedType, std::less<risk_queue_KeyType>, risk_queue_ShmemAllocator> risk_queue_MySHMMap; risk_queue_MySHMMap::iterator risk_queue_iter;
- 在engine.cpp中:
int main() { risk_queue_ShmemAllocator risk_queue_alloc_inst( risk_queue_segment.get_segment_manager()); cust_order_ShmemAllocator cust_order_alloc_inst( cust_order_segment.get_segment_manager()); for (; 0 < 1;) { boost::interprocess::offset_ptr<risk_queue_MySHMMap> risk_queue_m_pmap = risk_queue_segment.find<risk_queue_MySHMMap>("risk_queue").first; boost::interprocess::offset_ptr<cust_order_MySHMMap> cust_order_m_pmap = cust_order_segment.find<cust_order_MySHMMap>("cust_order").first; risk_queue_iter = risk_queue_m_pmap->begin(); if (risk_queue_iter != risk_queue_m_pmap->end()) { ordid = risk_queue_iter->second; cust_order_m_pmap->find(ordid)->second = o; o.ORDER_STATUS = '0'; o = cust_order_m_pmap->find(ordid)->second; risk_queue_m_pmap->erase(ordid); } }; return 0; }
intmain(){ 风险队列分配程序风险队列分配程序( 风险\队列\段。获取\段\管理器(); 客户订单分配器客户订单分配器( cust_order_segment.get_segment_manager()); 对于(;0<1;){ boost::进程间::偏移量\u ptr风险\u队列\u m\u pmap= 风险队列段。首先查找(“风险队列”); boost::进程间::偏移量\u ptr客户订单\u m\u pmap= 客户订单段。首先查找(“客户订单”); risk_queue_iter=risk_queue_m_pmap->begin(); 如果(risk\u queue\u iter!=risk\u queue\u pmap->end()){ ORDD=风险队列→第二; 客户订单pmap->find(ordid)->second=o; o、 订单_状态='0'; o=客户订单pmap->find(ordid)->秒; 风险队列\u m\u pmap->擦除(ORDD); } }; 返回0; }
engine: /usr/include/boost/intrusive/bstree.hpp:1331: boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::iterator boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::insert_unique_commit(boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::reference, const insert_commit_data&) [with ValueTraits = boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const int, event>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0, boost::intrusive::dft_tag, 3>; VoidOrKeyOfValue = void; VoidOrKeyComp = boost::container::value_to_node_compare<boost::container::container_detail::tree_node<std::pair<const int, event>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0, true>, boost::intrusive::tree_value_compare<boost::interprocess::offset_ptr<std::pair<const int, event>, long int, long unsigned int, 0>, std::less<int>, boost::container::container_detail::select1st<int>, false> >; SizeType = long unsigned int; bool ConstantTimeSize = true; boost::intrusive::algo_types AlgoType = (boost::intrusive::algo_types)5; HeaderHolder = void; boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::iterator = boost::intrusive::tree_iterator<boost::intrusive::bhtraits<boost::container::container_detail::tree_node<std::pair<const int, event>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0, true>, boost::intrusive::rbtree_node_traits<boost::interprocess::offset_ptr<void>, true>, (boost::intrusive::link_mode_type)0, boost::intrusive::dft_tag, 3>, false>; boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::reference = boost::container::container_detail::tree_node<std::pair<const int, event>, boost::interprocess::offset_ptr<void>, (boost::container::tree_type_enum)0, true>&; boost::intrusive::bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder>::insert_commit_data = boost::intrusive::insert_commit_data_t<boost::interprocess::offset_ptr<boost::intrusive::compact_rbtree_node<boost::interprocess::offset_ptr<void> >, long int, long unsigned int, 0> >]: Assertion `( p == this->end() || !this->comp()(*p, value) )' failed.
Aborted (core dumped)
engine:/usr/include/boost/intrusive/bstree.hpp:1331:boost::intrusive::bstree\u impl::iterator boost::intrusive::bstree\u impl::insert\u unique\u commit(boost::intrusive::bstree\u impl::reference,const insert\u commit\u data&)[with ValueTraits=boost::intrusive::bhtracts;voidWorkeyOfValue=void;voidWorkeyComp=boost::container::value_to_node_比较;SizeType=long unsigned int;bool ConstantTimeSize=true;boost::intrusive::algo_types AlgoType=(boost::intrusive::algo_types)5、 HeaderHolder=void;boost::intrusive::bstree\u impl::iterator=boost::intrusive::tree\u iterator;boost::intrusive::bstree\u impl::reference=boost::container::container\u detail::tree\u impl::insert\u commit\u data=boost::insert::insert\u commit\u data\u t]:断言`(p==this->->->end()| this->->comp()(*p,value))"失败了。
中止(堆芯转储)
请您帮助我理解错误。如果有更好的方法让我做我需要做的事情,请告诉我。好的,所以我查看了您的代码。您自己说过: 对内存空间的访问需要序列化 那你为什么不呢 笔记 简化标题:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
struct cust_order {
int ID;
char CLID[128];
int CUST_ID;
char ORDER_STATUS;
};
namespace bip = boost::interprocess;
namespace Shared {
using Segment = bip::managed_shared_memory;
using Manager = Segment::segment_manager;
template <typename T> using Alloc = bip::allocator<T, Manager>;
template <typename K, typename V, typename Cmp = std::less<K> >
using Map = bip::map<K, V, Cmp, Alloc<typename bip::map<K, V>::value_type> >;
}
using OrderTable = Shared::Map<int, cust_order>;
using RiskQueue = Shared::Map<int, int>;
这是完全令人困惑的,因为它将订单id视为“风险队列”的密钥?队列没有密钥,我们刚刚得出结论,风险的“密钥”指示优先级(因此它不是订单id)
即使猜测它应该是order\u table->erase(ordid)
,也没有多大意义,因为在删除之前设置订单状态的目的是什么
我只能断定这行代码是一个bug,需要修改
risk_queue->erase(it);
当然,在同步处理完成之前,这些都不重要
如果你有很多订单处理客户机,我建议你可以使用信号灯来代替。一切都会变得更加安全,也不会浪费CPU资源
如果您确实必须进行无锁数据访问,请确保数据结构实际上是无锁的,并且还确保保持一致性(这是一个困难的问题,因为您决定将数据拆分为两个结构)。您是否正在耗尽分配空间?6.25 MiB的内存不多(例如,查看是否使用较少的内存运行较短,使用较多的内存运行较长?)我现在将尝试报告分配是65536还是65536*100000似乎没有什么区别。不幸的是,其中两个程序在很长一段时间内运行良好,但当我引入第三个程序时,其中任何一个程序都会在30秒后停止运行,并显示错误消息。这让我相信在某些地方存在冲突供参考,其他程序与engine.cpp非常相似,它们在队列上连续循环,侦听订单ID,修改cust_order中的值,并从队列中删除订单ID。
risk_queue->erase(ordid);
risk_queue->erase(it);