【问题标题】:Moving a STL object between processes在进程之间移动 STL 对象
【发布时间】:2012-02-11 20:34:38
【问题描述】:

我知道这很奇怪,但我只是在玩。

我正在尝试通过两台机器之间的套接字在两个进程之间传输std::map(使用placement new 在内存的固定区域中实例化):MasterSlave。我正在使用的地图有这个typedef

   // A vector of Page objects
   typedef
      std::vector<Page*,
           PageTableAllocator<Page*> >
      PageVectorType;

   // A mapping of binary 'ip address' to a PageVector
   typedef
      std::map<uint32_t,
           PageVectorType*,
           std::less<uint32_t>,
           PageTableAllocator<std::pair<uint32_t, PageVectorType*> > >
      PageTableType;

PageTableAllocator&lt;T&gt; 类负责将 STL 容器可能需要/需要的任何内存分配到内存中的固定位置。例如,所有Page 对象和 STL 内部结构都在这个固定的内存区域中被实例化。这确保std::map 对象和分配器都 放置在内存的固定区域中。我使用 GDB 来确保映射和分配器的行为正确(所有使用的内存都在固定区域中,应用程序的正常堆上没有任何内容)。

假设Master 启动,初始化它的所有STL 结构和特殊内存区域,会发生以下情况。 Slave 启动,打印出它的页表版本,然后查找 MasterSlave 找到一个 master,删除它的页表版本,复制 Master 的页表版本(和特殊内存区域),然后成功打印出 Master的页表版本。根据我在 GDB 中所做的工作,我可以执行许多只读操作。

当尝试添加到新复制的PageTableType 对象时,分配器的void construct (pointer p, const T&amp; value) 方法中的Slave 错误。作为p 传入的值指向已分配的内存区域(根据Masterstd::map 版本)。

我对 C++ 对象结构一无所知,但我猜测 SlavePageTableType 版本中的对象状态即使在我替换了 @987654344 的所有内存之后也必须存在@ 及其使用的分配器。 我的问题是这是否是一个有效的担忧。 C++ 是否在对象实例化 din 的内存区域之外维护某种对象状态?

地图中使用的所有对象都是非 POD。分配器也是如此。

【问题讨论】:

  • 您将决定共享内存的哪一部分已分配的元数据存储在哪里?
  • 我在我的应用程序中重新定义了所有对内存分配代码(mallocfree 等)的调用。当一个节点分配内存时,偏移量记录在这个std::map对象中。当Slave 尝试更新地图(传输后)时,它会出错。
  • 这就是我的意思。录制在哪里
  • std::map 是在另一个固定的内存区域中使用placement new 实例化的。
  • 您是否尝试实现自己的共享内存功能?你考虑过this question吗?

标签: c++ stl


【解决方案1】:

回答您的具体问题:

C++ 是否在对象被实例化的内存区域之外维护某种对象状态?

答案是。没有设置其他数据结构来“跟踪”对象或任何类似的东西。 C++ 使用显式内存分配模型,因此如果您选择负责分配和解除分配,那么您将拥有完全的控制权。

我怀疑您的代码在某处有问题,但由于您认为代码是正确的,因此您正在发明一些其他原因导致您的代码可能会失败,并改为遵循该路径。我会退后一步,仔细检查你的代码现在的工作方式,看看你是否能确定问题所在。尽管 STL 类很复杂(尤其是 std::map),但它们最终只是代码,并没有隐藏的魔力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多