Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost进程间:在循环中分配共享内存_C++_Memory_Boost - Fatal编程技术网

C++ Boost进程间:在循环中分配共享内存

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;

我正在使用boosts进程间库在多个程序之间共享内存。3或4个其他程序将按客户顺序读取和写入共享内存内容。对内存空间的访问需要序列化

在下面的示例程序中,引擎在risk_队列的内容上循环,如果已填充,则获取第一个客户订单号并定位该订单以进行处理

  • 在每个程序使用的objects.h头文件中:

    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;
    
    结构客户订单{ 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::进程间::映射 风险队列地图; 风险队列:迭代器风险队列;
  • 在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))"失败了。
中止(堆芯转储)
请你帮我理解错误。如果有更好的方法让我做我需要做的事情,请告诉我

但要使这项工作正常,我必须在循环中分配内存

我不明白为什么会是这样。您的共享内存大小限制为64kb(65536字节),所以这是一个简单的问题:预先分配一次

我的应用程序是面向低延迟的,我想知道是否有一种方法可以读取内存中更新的对象,而不必在每次循环迭代中不断地重新分配

是的。索引到映射到进程地址空间的共享内存区域,而不进行分配

下面是我必须放在循环中的代码,以便从访问相同内存空间的其他程序接收更新

您显示的代码没有分配任何东西。它在托管段中定位已分配(和构造)的对象,并返回指向该对象的指针

如果我把它放在循环之外,当其他程序在共享内存空间中操作或添加数据时,我将不会收到更新

啊哈!您没有告诉我们
X_MySHMMap
是什么样子的,但我可以猜测它可能包含类似
std::array
的内容,或者您循环的另一个容器

如果您从多个进程对该对象进行非同步访问,则输入一个。编译器有一个内存模型(请参见同一页),允许它重新排序内存操作并消除加载/存储周期。例如,如果您写入

 static bool ready = false;
 int main() {
      while (!ready) {
           std::cout << "waiting...\n";
      }
 }

⑨(线程在另一个进程中没有区别)
²Coliru不允许共享内存访问

感谢@sehe的详细说明。我当时的印象是,我可以在程序的循环之外分配内存空间,并为其编制索引。如果这不可能,在循环内编制索引会有很大的开销吗?我已经更新了我的帖子,加入了一些代码。我在网上找不到任何c澄清了msm和smo之间的区别。你能解释一下吗?顺便说一下,访问需要在访问内存的所有程序中序列化。当一个程序正在访问时,其他程序必须等待。我需要实现互斥锁吗?嗯?我的代码正好说明了这一点。既然你仍然感到困惑,你能显示实际的(自包含的)吗代码?我已将问题编辑为包含相关代码。感谢您迄今为止的帮助。
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <array>
#include <atomic>

using SharedBuffer = std::array<std::atomic_char, 65536>;
static_assert(std::is_pod<SharedBuffer>{}, "assumed POD"); // Warning: trait is not correct on some versions of MSVC

namespace bip = boost::interprocess;

int main() {
    bip::shared_memory_object smo(bip::open_or_create, "yoho", bip::mode_t::read_write);
    smo.truncate(sizeof(SharedBuffer));

    bip::mapped_region region(smo, bip::mode_t::read_write, 0, 65536);
    auto& buffer = *reinterpret_cast<SharedBuffer*>(region.get_address());

    // do something with that buffer
    std::fill(buffer.begin(), buffer.end(), 0); // start with all zeroes

    // loop over it or something
}