共享内存中的STL容器(Windows)

STL containers in shared memory (Windows)

本文关键字:Windows 容器 STL 内存 共享      更新时间:2023-10-16

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

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

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

感谢

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

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

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

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

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

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

使用具有boost::interprocess的标准兼容STL集合的真正问题是,该标准明确允许集合假设相同类型的分配器是等效的,分配器不需要任何存储状态,并且可以忽略指针类型,而代之以使用t*。

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

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

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