3

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

4

2 回答 2

1

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

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

于 2009-07-10T18:22:47.373 回答
-1

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

于 2009-07-10T18:36:02.963 回答