如何通过 boost::interprocess 在向量中构造向量
Posted
技术标签:
【中文标题】如何通过 boost::interprocess 在向量中构造向量【英文标题】:How to construct vector in the vector by boost::interprocess 【发布时间】:2014-01-08 05:55:46 【问题描述】:我已经了解了有关“在 shared_memory 中创建向量”的 boost 示例。 现在我的数据结构是这样的:
数据结构:
enum FuncIndex
enmFunc_glBegin,
...
class CGLParam ;
class Funcall
vector<CGLParam> vecParams;
;
class Global_Funcall
typedef allocator<CGLParam*, managed_shared_memory::segment_manager> ShmemAllocator;
typedef vector<CGLParam*, ShmemAllocator> MyVector;
MyVector<FunCall> vecFuncalls;
;
Global_Funcall()
shared_memory_object::remove("MySharedMemory");
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocator alloc_inst(segment.get_segment_manager());
//Construct a vector named "MyVector" in shared memory with argument alloc_inst
vecFuncalls= segment.construct<MyVector>("MyVector")(alloc_inst);
void InvokeFuncs(CGLParam *presult)
managed_shared_memory open_segment(open_only,"MySharedMemory");
listParams = open_segment.find<MyVector>("MyVector").first;
// MyVector::const_iterator it;
// for (it = listParams->cbegin(); it != listParams->cend(); it++)
//
// (*it)->InvokeFunc(presult);
//
我的问题是“如何构造 vecParams 以及如何获取它”。数据量很大(opengl 函数调用) 该结构用于保存opengl函数调用。
【问题讨论】:
看来您在使用 C++ 语言时遇到了真正的问题。没关系。但我建议不要使用 C++ 中的进程间技术,除非您绝对必须同时学习这两个复杂的主题。 (我很确定 python 或 c#-4.0 将拥有处理大型数据集所需的工具。) 如果这只是关于大型数据集,STXXL 可能对您有用。 【参考方案1】:除了“明显的”错别字之外,您还尝试将 IPC 向量 (MyVector*
) 分配给 GlobalFuncall
构造函数中的标准 向量。那永远行不通。 C++ 是一种强类型语言,所以类型必须匹配才能赋值[1]。
除此之外似乎还有一个概念问题:
如果目标是收集可能比物理内存更大的数据集,那么共享内存本身就无济于事。您需要查看内存映射文件 如果您想要共享内存,因为您可以在进程之间共享它(因此 Boost Interprocess),您将需要考虑进程同步,否则您将看到由于数据竞争而导致的复杂错误。 您无法在此容器中安全地存储原始指针。相反,将实际元素存储在那里(或者也许如果你想获得真正的花哨,请查看bip::offset_ptr<>
)。
这是一个“修复”演示
修复 C++ 编译问题, 将元素类型更改为CGLParam
而不是CGLParam*
修复成员类型以匹配 SHM 向量和
添加基本的共享互斥锁同步(这本身就是一门艺术,您会想了解更多相关信息)
看Live On Coliru[1]
#include <vector>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_recursive_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
namespace bip = boost::interprocess;
using mutex_type = bip::named_mutex;
class CGLParam ;
typedef bip::allocator<CGLParam, bip::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<CGLParam, ShmemAllocator> MyVector;
class Funcall
std::vector<CGLParam> vecParams;
;
struct mutex_remove
mutex_remove() mutex_type::remove("2faa9c3f-4cc0-49c5-8f79-f99ce5a5d526");
~mutex_remove() mutex_type::remove("2faa9c3f-4cc0-49c5-8f79-f99ce5a5d526");
remover;
static mutex_type mutex(bip::open_or_create,"2faa9c3f-4cc0-49c5-8f79-f99ce5a5d526");
class Global_Funcall
MyVector* vecFuncalls;
Global_Funcall()
bip::scoped_lock<mutex_type> lock(mutex);
bip::shared_memory_object::remove("MySharedMemory");
bip::managed_shared_memory segment(bip::create_only, "MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocator alloc_inst(segment.get_segment_manager());
//Construct a vector named "MyVector" in shared memory with argument alloc_inst
vecFuncalls = segment.construct<MyVector>("MyVector")(alloc_inst);
;
void InvokeFuncs(CGLParam *presult)
bip::scoped_lock<mutex_type> lock(mutex);
bip::managed_shared_memory open_segment(bip::open_only, "MySharedMemory");
auto listParams = open_segment.find<MyVector>("MyVector").first;
MyVector::const_iterator it;
for (it = listParams->cbegin(); it != listParams->cend(); it++)
//it->InvokeFunc(presult);
int main()
[1] 当然,除非有合适的转换
[2] Coliru 不支持所需的 IPC 机制:/
【讨论】:
我这样做是有原因的。如果我将所有 CGlParam 放入一个向量中。很难确定函数调用的名称以及要调用多少个参数。 @sehe :关于您的代码的快速问题,segment
变量将在 GlobalFuncall ctor 的末尾被销毁,对吧?因为它超出了范围!共享内存肯定会保留,但是该进程可能未映射内存,对吗?不确定,只是问问。以上是关于如何通过 boost::interprocess 在向量中构造向量的主要内容,如果未能解决你的问题,请参考以下文章
如何从 boost::interprocess::managed_shared_memory 对象中获取 shmid
boost::interprocess::managed_mapped_file 如何包含弹性向量?
这些 Boost::Interprocess 组件是不是需要同步?
boost::interprocess::map - 如何使用 basic_string 作为类型更新值