【问题标题】:Storing vector or any other container in a boost interprocess shared_memory_object?在 boost 进程间 shared_memory_object 中存储向量或任何其他容器?
【发布时间】:2015-11-23 08:28:24
【问题描述】:

我知道boost interprocess containers,示例使用托管共享内存。但我想使用一个简单的boost::interprocess::shared_memory_object,它里面有一个对象,以及该对象内的向量或任何其他容器。这似乎行不通。

试过这个:

#include <stack>
#include <boost/interprocess/containers/vector.hpp>

namespace bip = boost::interprocess;

class SharedMemoryMetadata
{
public:
    std::stack<unsigned short> newData;
    int deleteme;
    bip::vector<unsigned short> v;
};

并创建共享内存:

bip::shared_memory_object::remove(OUTPUT_METADATA_MEMORY_SEGMENT_NAME);
sharedMemoryMetadataForOutput = new bip::shared_memory_object(bip::create_only, OUTPUT_METADATA_MEMORY_SEGMENT_NAME, bip::read_write);//use old shared memory if exists else create a new one
sharedMemoryMetadataForOutput->truncate(sizeof(SharedMemoryMetadata)+ (3*sizeof(unsigned int)*MAX_NUMBER_OF_OBJECTS_EXPECTED_TO_BE_IN_SHARED_MEMORY));//set the size of the memory object
sharedMemoryMetadataRegion = new bip::mapped_region(*sharedMemoryMetadataForOutput, bip::read_write);//map the whole shared memory in this process
void* sharedMemorySegmentForMetadataStorage = sharedMemoryMetadataRegion->get_address();//get the region address
sharedMemoryMetadataObject = new (sharedMemorySegmentForMetadataStorage) SharedMemoryMetadata();//create a shared memory buffer in memory

我尝试通过以下方式访问它:

bip::shared_memory_object* sharedMemoryMetadataForOutput;
SharedMemoryMetadata* sharedMemoryMetadataObject;
bip::mapped_region* sharedMemoryMetadataRegion;

bip::shared_memory_object* sharedMemoryMetadataForOutput;
SharedMemoryMetadata* sharedMemoryMetadataObject;
bip::mapped_region* sharedMemoryMetadataRegion;  
sharedMemoryMetadataForOutput = new bip::shared_memory_object(bip::open_only, OUTPUT_METADATA_MEMORY_SEGMENT_NAME, bip::read_write);//create a shared memory object http://blog.wolfgang-vogl.com/?p=528
sharedMemoryMetadataRegion = new bip::mapped_region(*sharedMemoryMetadataForOutput, bip::read_write);//Map the whole shared memory in this process        
void * sharedMemorySegmentForMetadataStorage = sharedMemoryMetadataRegion->get_address();//get the region address
sharedMemoryMetadataObject = static_cast<SharedMemoryMetadata*>(sharedMemorySegmentForMetadataStorage);//Obtain the shared structure

正如预期的那样,std::stack&lt;unsigned short&gt; newData; 被证明是空的,即使有东西被写入堆栈。但是如果我给int deleteme 赋值,我就可以从另一个访问共享内存的程序中读取它。

push_backbip::vector&lt;unsigned short&gt; v; 有效,但是当我尝试从其他程序访问它时,我遇到了分段错误。有没有办法可以存储和访问shared_memory_object 中的向量,或者只能使用托管共享内存?即使我使用托管共享内存,如何将向量存储在SharedMemoryMetadata 类中,如上所示?

【问题讨论】:

    标签: c++ boost-interprocess


    【解决方案1】:

    我将以向量为例进行解释。基本上,std::vector 是这样的:

    template<typename T>
    struct vec {
      std::size_t size;
      T * data;
    };
    

    当您将它放入任何共享内存时,您共享的本质上是一个大小和一个指针

    当您向向量添加元素时,它会向其分配器 请求内存以将它们存储到其中。在您的示例中,这是默认分配器std::allocator,它又调用operator new

    因此,向量从 非共享 堆内存中获取内存以存储其元素。因此,指向此(非共享)内存的(共享)指针将在其他地址空间中无效,从而导致未定义的行为。

    要解决这个问题,您要么需要一个知道被共享(或为此而设计)的向量,要么您自己编写一个从共享内存分配的分配器,并将其与 STL 类一起使用。

    【讨论】:

    • 谢谢。我已经知道分配概念。我希望我收到的是一个解决方案或一段工作代码。如果没有简单的解决方案,我会继续删除我的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2014-12-06
    • 2021-12-15
    • 2019-12-07
    相关资源
    最近更新 更多