如何通过 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&lt;&gt;)。

这是一个“修复”演示

修复 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 作为类型更新值

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

Boost.Interprocess内存位置