【问题标题】:Is it Possible to Place Vectors Containing Pointers into Shared Managed Memory?是否可以将包含指针的向量放入共享托管内存中?
【发布时间】:2015-02-11 13:36:32
【问题描述】:

我想快速将一个包含指针向量的对象传递给另一个进程。这就是我要发送的内容:

typedef std::vector<Shelve*> ShelveVec;

这是我尝试过的:

managed_shared_memory segment{create_only, "HwDescriptionObjects", 1056};

BeBoardInterface *sBeBoardInterface = segment.construct<BeBoardInterface>("BeBoardInterface")(fBeBoardFWMap);
CbcInterface *sCbcInterface = segment.construct<CbcInterface>("CbcInterface")(fBeBoardFWMap);
ShelveVec *sShelveVector = segment.construct<ShelveVec>("ShelveVector")(fShelveVector, alloc_inst);

qDebug() << "Size " << sShelveVector->size();

前两个共享内存对象可以工作,但我已经尝试了从阅读 BOOST 文档中了解到的向量,由于begin 指针分配之类的原因,实现起来有点棘手。当从进程中访问时,它最终是空的。

这是否可行?

编辑,我可以提供尽可能多的信息:

我做了一系列循环来初始化这些类:

uint32_t cNShelve = 0
for(auto &kv : mapSettings.keys())
{
    cShelveId=kv;
    fShelveVector.push_back(new Shelve(cShelveId));
    for(auto &kv_ : mapSettings.value(kv).keys()):
    {
        cBeId = kv_;
        BeBoard* cBeBoard = new BeBoard(cShelveId, cBeId);
        fShelveVector.at(cNShelve)->addBoard(cBeBoard);
    }
cNShelve++;
}

Edit2:一种廉价的解决方案:

managed_shared_memory segment{create_only, "HwDescriptionObjects", 1056};
uint32_t cNShelve = 0
for(auto &kv : mapSettings.keys())
{
    cShelveId=kv;
    Shelve *sShelve = segment.construct<Shelve>("Shelve")(cShelveId)
    fShelveVector->push_back(sShelve);
    for(auto &kv_ : mapSettings.value(kv).keys()):
    {
        cBeId = kv_;
        BeBoard* cBeBoard = segment.construct<BeBoard>("BeBoard")(cShelveId, cBeId);
        fShelveVector.at(cNShelve)->addBoard(cBeBoard);
    }
cNShelve++;
}

Contents of the HwDescription Objects

【问题讨论】:

  • 我添加了一个较小的版本
  • 我已经更新了我的答案。由于缺少类型定义,无法真正进入演示。我知道你不能分享。希望这些链接对您有用
  • 基本上我有一些东西可以创建所有这些对象,我希望其他进程可以单独使用这些对象,而不必重新初始化它们。据我所知,我有两条路径 - 套接字序列化/反序列化或共享内存。你认为这是一条明智的道路吗?
  • 取决于使用模式。我认为 construct&lt;&gt; 每个对象都可能会产生巨大的开销(参见例如bad_alloc is thrown)和How do I measure the size of a boost interprocess vector in shared memory?)。所以是的,对于许多小对象——你不想/不能让分配器感知——我建议序列化

标签: c++ boost shared-memory


【解决方案1】:

你可以。

但是,您必须确保指针从共享内存中分配。

如果你展示 SSCCE,我会告诉你我会怎么做。


更新

查看更新后的问题后,我必须说它会涉及。您需要从共享内存中分配 Shelves,对于现在从堆中分配的所有胆量[1](如 BeBoards)也是如此。

建议:

  1. 如果你真的只需要指针作为标识,别担心
  2. 也许您可以只共享向量索引(以防它们在其他进程空间中有意义)
  3. 如果您让类分配器感知,您可以使用boost::container::scoped_allocator_adaptor 来减轻一点痛苦。

    我在以下答案中使用范围分配器(来自 Boost)创建了演示:


[1](从技术上讲,至少是您从跨进程边界访问的部分)

【讨论】:

  • 那么你的意思是,如果我将一个对象初始化到共享内存中并将它们添加到一个向量中,它可能实际上不起作用?如果在对象内部初始化了任何指针 - 例如 BeBoard 在自身内部初始化一个对象 - 那也需要存储在共享内存中吗?据我所知,我认为这些对象实际上只包含 POD——只是映射,可能还有字符和字符串的向量——内部没有初始化指针。我添加了一个答案尝试并包含了我正在使用的代码。
  • 简单的准则是,您不能使用来自进程内不同进程空间的原始指针。从那里逻辑上遵循所有约束/漏洞。什么时候是 POD 无关紧要——而不是涉及指针时(指针 - 是 - POD,但它们对于其他进程中的间接无效)
  • 感谢您提供的非常丰富的答案。如果我能超过 1up upi,我会 =D
猜你喜欢
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 2011-07-18
  • 2011-01-30
  • 1970-01-01
  • 2013-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多