【问题标题】:STL containers in shared memory (Windows)共享内存中的 STL 容器 (Windows)
【发布时间】:2012-09-18 13:08:08
【问题描述】:
我正在开发一个由 2 个必须共享一些数据结构的进程组成的应用程序。这些类被组织在不同的库中,并且这些库用于不同的应用程序。
那么,还有其他方法可以使用 STL(在 Windows 中)共享类或结构吗?目标是不要在我们的库中对 Boost 产生过多依赖。
谢谢
【问题讨论】:
标签:
c++
winapi
stl
boost-interprocess
【解决方案1】:
Boost.Interprocess 拥有自己的容器类的原因是大多数当前的实现并不完全支持分配器方面的标准。
Boost.Interprocess 容器类是标准容器的完全兼容实现,因此您可以将它们用作标准容器的直接替代品,并在它们被固定为支持标准分配器时切换到供应商提供的容器协议。
我不确定我是否能比documentation更好地解释它,但最大的问题是共享内存映射到不同虚拟地址的不同进程,所以容器内使用的任何指针必须 是一个相对 指针(例如从段的开头)。标准分配器模型支持这一点,但容器也必须通过使用Allocator::pointer 而不是T * 来支持这一点。当所有实现都被修复以支持这一点时,将不再需要 Boost.Interprocess 容器。
或者,您也许能够映射内存at the same virtual address in each process;如果你这样做,那么你可以使用现有实现的容器,因为原始指针将正常工作。
【解决方案2】:
就个人而言,我会避免使用共享结构方法。另一种方法是将结构的所有权授予两个过程之一。另一个进程将通过向第一个进程发送消息来访问它。
如果您完全决定使用共享内存,那么您当然可以将它与 STL 一起使用。首先,您必须为您的容器创建一个自定义分配器。分配器将从共享内存块中分配内存。此外,由于 STL 容器不是线程安全的,因此您必须使用命名互斥体为容器编写同步包装器。
【解决方案3】:
将符合标准的 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