【问题标题】:Is boost::managed_shared_memory using a file on my hard drive?boost::managed_shared_memory 是否使用我硬盘上的文件?
【发布时间】:2020-02-17 14:42:31
【问题描述】:

当我创建一个新的boost::interprocess::managed_shared_memory 时,我可以看到C:\ProgramData\boost_interprocess\1571641094\NAME_OF_SHARED_MEMORY 中出现了一个文件,该文件的大小似乎与创建的共享内存的大小相匹配。

我从documention 的理解是,有两个广泛使用的对象可用于在进程之间共享内存(在managed_shared_memory 的范围内):

  • basic_managed_shared_memory
  • basic_managed_mapped_file

managed_shared_memory 使用basic_managed_shared_memory 实现。我认为这个实现是正确的共享内存,而不是内存映射文件

看到它使用文件让我感到困惑。这两个托管共享内存都基于内存映射文件实现吗?

Windows 上唯一避免内存映射文件的 boost 共享内存解决方案是 windows_shared_memory 吗?

注意:我在 Windows 10 上,在 VS2013 上使用 VC++。

使用managed_shared_memory 时可以重现在ProgramData 中创建文件的行为的代码示例:

#include <boost/interprocess/managed_shared_memory.hpp>

int main(int argc, char *argv[])
{
  boost::interprocess::permissions permissions;
  permissions.set_unrestricted();

  boost::interprocess::managed_shared_memory* sharedMemory;
  sharedMemory = new boost::interprocess::managed_shared_memory(
  {
    boost::interprocess::open_or_create,
    "NAME_OF_SHARED_MEMORY",
    400000,
    0,
    permissions
  }
  );

  return 0;
}

【问题讨论】:

    标签: c++ boost shared-memory boost-interprocess


    【解决方案1】:

    你的假设是正确的。 Boost 文档中的“Emulation for systems without shared memory objects”部分解释了发生了什么:

    Boost.Interprocess 在 POSIX 方面提供可移植的共享内存 语义。一些操作系统不支持共享内存,因为 由 POSIX 定义:

    • Windows 操作系统使用由分页文件支持的内存提供共享内存,但生命周期语义不同 来自 POSIX 定义的那些(参见 Native windows shared memory 部分了解更多信息)。

    ...

    在这些平台中,共享内存是通过映射文件来模拟的 在临时文件中创建的“boost_interprocess”文件夹中创建 目录。在 Windows 平台中,如果“Common AppData”键存在于 注册表,“boost_interprocess”文件夹在该目录中创建 (在 XP 中通常是“C:\Documents and Settings\All Users\Application Data” 在 Vista 中“C:\ProgramData”)。对于没有它的 Windows 平台 注册表键和Unix系统,共享内存是在系统中创建的 临时文件目录(“/tmp”或类似)。

    由于这种模拟,共享内存的文件系统生命周期为 其中一些系统。

    正如您已经指出的那样,作为替代方案,您可以使用native windows shared memory 对象(使用windows_shared_memory)。它将使用由页面文件支持的共享内存对象,而不是在C:\ProgramData 中创建的文件。通常,这不会使用文件系统(请参阅:https://stackoverflow.com/a/6215317/79111)。如果不考虑可移植性,这可能是一种更好的方法,因为它允许与使用共享内存但不依赖 Boost.Interprocess 的其他应用程序进行互操作。

    【讨论】:

    • 关于最后一段,正常情况下不会不会打到磁盘上;见stackoverflow.com/a/6215317/214671
    • @MatteoItalia,谢谢我已经更正了这个段落。
    • @TonvandenHeuvel 非常感谢!这回答了我的很多问题。出于好奇,我们使用文件系统这一事实是否意味着可以安全地假设存储在manged_shared_memory 中的数据在重新启动后仍然存在,因为它是基于文件系统的?或者它不是一种受支持的行为,并且被认为可以并且最终会被操作系统擦除的临时数据?
    • @Norgannon,不,你不能做出这样的假设。一旦不再有任何进程连接到共享内存块,它就会自动销毁。 Windows 会为您解决这个问题。这实际上很方便,在 POSIX 下,您必须手动清理共享内存文件,这在某些极端情况下会变得很棘手。当然,您仍然可以在重新启动后获得持久性,但是您将不得不在进程停止之前的某个时间写出数据以归档自己。
    • 好的,明白了!再次,非常感谢所有这些信息:D
    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 2014-05-06
    • 1970-01-01
    相关资源
    最近更新 更多