从 boost 共享内存中转储数据的最佳方法

Posted

技术标签:

【中文标题】从 boost 共享内存中转储数据的最佳方法【英文标题】:Best way to dump data from boost shared memory 【发布时间】:2017-08-22 19:18:51 【问题描述】:

我有 2 个申请。一个写入高频数据来提升托管共享内存,数据结构是提升双端队列。

typedef boost::interprocess::allocator<REALTIME_INFO, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef boost::interprocess::deque<REALTIME_INFO, ShmemAllocator> MyDeque;

boost::interprocess::managed_shared_memory segment(boost::interprocess::open_or_create, "MySharedMemory",50000000); 
const ShmemAllocator alloc_inst (segment.get_segment_manager());
MyDeque *Mydeque;
Mydeque = segment.find_or_construct<MyDeque>("myd")(alloc_inst);//first ctor parameter

if(Mydeque->size() < 150000)   
    Mydeque->push_back(rtinfo);

else
    Mydeque->pop_front();
    Mydeque->push_back(rtinfo);

当按下按钮时,我的第二个应用程序是 Qt 应用程序,它从共享内存中读取数据并写入 csv 文件。由于数据很大,我无法直接从共享内存中写入数据,所以我尝试了 memcpy。我只能得到第一个值,剩下的就是垃圾。

managed_shared_memory segment (open_only, "MySharedMemory");
MyDeque *Mydeque = segment.find<MyDeque>("myd").first;

获得第一个指针后,我尝试将其复制到另一个MyDeque,但我只能访问第一个指针,无法迭代剩余数据。

memcpy(Mydeque_new, &Mydeque, Mydeque->size()*sizeof(REALTIME_INFO));

谁能建议一种更好的方法将数据从共享内存复制到本地内存。

【问题讨论】:

您使用什么策略来避免数据竞争?从您排队代码的外观来看,您似乎需要同时从两个应用程序访问,所以我想限制对整个内存块的访问对您不起作用。你如何处理这将告知哪种策略是合适的。 我们可以怀疑REALTIME_INFO 是一个POD吗?还有@Frank 所说的:防止竞争条件。 @Frank 其实你是对的。我尝试使用 named_mutex 但这开始使第二个应用程序崩溃。由于 managed_shared _memory 是自动同步的,我想不使用任何互斥锁。这仍处于初始阶段。你能指出我使用互斥锁的正确方向吗? @user0042 REALTIME_INFO 是用户定义的数据结构。我同意弗兰克的观点。我也试过 scoped_lock。 @brownKnight 恐怕这在很大程度上取决于我们无法回答的两个可执行文件之间交互的性质。 【参考方案1】:
memcpy(Mydeque_new, &Mydeque, Mydeque->size()*sizeof(REALTIME_INFO));

这是大胖子Undefined Behaviour,因为deque&lt;&gt; 不是 POD 类型。事实上,即使是元素数据在内存中也不连续,所以你甚至不能memcpy 那个

考虑使用Boost Interprocess Message Queue

如果只有一个消费者和一个生产者,请考虑使用spsc_queue:Shared-memory IPC synchronization (lock-free)。这是一个潜在的无锁解决方案,它也有一个批量出队/入队接口。

【讨论】:

以上是关于从 boost 共享内存中转储数据的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

如何直接在boost共享内存中编写opencv cv :: Mat图像

Boost:shared_memory_object --- 共享内存

在没有共享内存的情况下提升进程间字符串

使用 Boost.Interprocess 使进程等待直到资源加载到共享内存中

boost的问题:进程间共享内存

boost::interprocess 不在共享内存副本中的容器容器