3

我正在开发一个由 2 个必须共享一些数据结构的进程组成的应用程序。这些类被组织在不同的库中,并且这些库用于不同的应用程序。

  • 我的第一次尝试是在 Win32 中使用命名共享内存,但这里的问题是我不能使用 STL 容器。
  • 在寻找解决方案时,我找到了Boost Interprocess,如果我理解的话,我必须将我的类中的所有 STL 容器更改为“STL”Boost Interprocess 容器。

那么,有没有其他方法可以使用 STL(在 Windows 中)共享类或结构?目标是不要在我们的库中对 Boost 产生过多的依赖。

谢谢

4

3 回答 3

7

Boost.Interprocess 拥有自己的容器类的原因是大多数当前的实现并不完全支持分配器方面的标准。

Boost.Interprocess 容器类是标准容器的完全兼容实现,因此您可以将它们用作标准容器的直接替代品,并在它们被修复以支持标准分配器协议时切换到供应商提供的容器。

我不确定我是否能比文档更好地解释它,但最大的问题是共享内存被映射到不同虚拟地址的不同进程,因此容器内使用的任何指针都必须相对指针(例如来自段的开头)。标准分配器模型支持这一点,但容器也必须通过使用Allocator::pointer而不是来支持这一点T *。当所有实现都被修复以支持这一点时,将不再需要 Boost.Interprocess 容器。

或者,您可以在每个进程中将内存映射到相同的虚拟地址;如果您这样做,那么您可以使用现有实现的容器,因为原始指针将正常工作。

于 2012-09-18T13:17:40.477 回答
1

就个人而言,我会避免使用共享结构方法。另一种方法是将结构的所有权授予两个过程之一。另一个进程将通过向第一个进程发送消息来访问它。

如果您完全决定使用共享内存,那么您当然可以将它与 STL 一起使用。首先,您必须为您的容器创建一个自定义分配器。分配器将从共享内存块中分配内存。此外,由于 STL 容器不是线程安全的,因此您必须使用命名互斥锁为容器编写同步包装器。

于 2012-09-18T13:22:05.963 回答
1

将符合标准的 STL 集合与 boost::interprocess 一起使用的真正问题是,该标准明确允许集合假定相同类型的分配器是等价的,分配器不需要任何存储状态,并且可以忽略指针类型并且可以使用 T* 代替。

boost::interprocess 文档比我更好地解释了这一点,但我的总结是:

  • C++ 标准允许无状态或有状态分配器
  • 即使分配器指定了另一种类型,C++ 标准也允许将 T* 用于指针
  • boost::interprocess 需要有状态分配器支持(因此拥有的内存段可以在所有分配中使用)
  • 对于大多数用途,boost::interprocess 使用替代指针类型 - 对于非平凡的应用程序,这将是 offset_ptr
  • boost::interprocess 集合 - map/vector/etc -(这些是当前 boost::container 类型的 typedef)提供了 boost::interprocess 所需的所有这些可选实现细节

因此,即使您当前的 STL 集合支持 boost::interprocess 的要求,而且它们可能不支持,C++ 标准也不能保证它们将来会继续提供这些要求。对于 boost::interprocess 应用程序中使用的集合,唯一明智的方法是使用保证符合 boost:interprocess 要求的 boost 集合——来自 boost::container 或 boost:interprocess:collections

于 2015-07-30T23:23:29.420 回答