【问题标题】:How to emulate shm_open on Windows?如何在 Windows 上模拟 shm_open?
【发布时间】:2010-11-09 19:34:43
【问题描述】:

我的服务需要存储一些信息(至少,至少 20 位左右,但我可以轻松利用更多),以便

  • 即使服务崩溃或以其他方式异常终止,它也会在服务重新启动后持续存在
  • 它不会在重新启动后持续存在
  • 只需很少的开销即可读取和更新

如果我将此信息存储在注册表或文件中,系统重新启动时不会自动清空。

现在,如果我在现代 POSIX 系统上,我会使用 shm_open,这将创建一个共享内存段,该段在进程重新启动但不会在系统重新启动时持续存在,如果出现以下情况,我可以使用 shm_unlink 清理它持久性数据不知何故损坏了。

我找到了MSDN : Creating Named Shared Memory 并开始在我的服务中重新实现它;这基本上使用CreateFileMapping(INVALID_HANDLE_NAME, ..., PAGE_READWRITE, ..., "Global\\my_service") 而不是shm_open("/my_service", O_RDWR, O_CREAT)

但是,我有一些顾虑,尤其是围绕此页面文件支持的映射的生命周期。我在 MSDN 文档中没有找到这些问题的答案:

  • 映射是否在重新启动后仍然存在?
  • 如果没有,当所有打开的句柄都关闭时,映射是否会消失?
  • 如果没有,有没有办法删除或清除映射?使用时不需要。

如果它确实在重新启动后仍然存在,或者在未引用时确实消失了,或者无法手动重置,那么这种方法对我来说毫无用处。

您能否验证或找出这些点的错误,和/或推荐不同的方法?


如果有一个目录保证在重新启动时被清除,我可以将数据保存在一个临时文件中,但它仍然不是理想的:在某些系统负载下,我们遇到文件打开/写入失败(罕见,不到 0.01% 的时间,但仍在发生),并且此功能将在日志记录路径中使用。这里就不多介绍文件操作了。

【问题讨论】:

    标签: windows winapi ipc shared-memory


    【解决方案1】:

    共享内存映射不会在重新启动后持续存在,并且会在其所有句柄关闭时消失。内存映射对象是一个内核对象——它们总是在对它们的最后一个引用消失时被删除,无论是通过 CloseHandle 显式地通过还是在包含引用的进程退出时。

    尝试使用 RegCreateKeyEx 和 REG_OPTION_VOLATILE 创建注册表项 - 卸载相应的配置单元时不会保留数据。这将在 HKLM 的系统关闭或 HKCU 的用户注销时发生。

    【讨论】:

    • 感谢您确认我目前的方法存在缺陷;我得出了这个结论,但还没有进行测试。 REG_OPTION_VOLATILE in HKLM 看起来很合适,我只需要解决一些内部注册表包装器。
    【解决方案2】:

    听起来您可能想要序列化而不是共享内存?如果这确实适合您的应用程序,那么您的序列化方式将取决于您的语言。如果您使用的是 c++,请查看 boost::serialize。 C# 无疑有很多序列化选项(如 java),如果你正在使用的话。

    【讨论】:

    • 序列化不是问题;问题是要完全正确地获取序列化数据的生命周期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多