代码之家  ›  专栏  ›  技术社区  ›  ephemient

如何模拟在Windows上打开的shm_?

  •  3
  • ephemient  · 技术社区  · 15 年前

    我的服务需要存储一些信息(至少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%的时间,但仍在发生),此功能将用于日志路径。我不想在这里介绍更多的文件操作。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Michael    15 年前

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

    尝试用创建注册表项 RegCreateKeyEx 使用Reg_选项_volatile-卸载相应的配置单元时,数据不会保留。这将在系统关闭时为hklm或用户注销为hkcu。

        2
  •  -1
  •   Mike Ellery    15 年前

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