如何在Windows上模拟shm_open?

3
我的服务需要存储一些信息(至少20位,但我可以很容易地利用更多),以便:
  • 即使服务崩溃或被非正常终止,它也会持久存在于服务重启之间
  • 它不会在重新启动后持久存在
  • 可以使用非常少的开销读取和更新
如果我将此信息存储在注册表或文件中,则系统重新启动时不会自动清空。
现在,如果我在现代POSIX系统上,我会使用shm_open,它将创建一个共享内存段,该段在进程重启时持久存在,但不会在系统重新启动时持久存在,我可以使用shm_unlink来清理它,如果持久数据出现错误。
我发现 MSDN : 创建命名共享内存 并开始在我的服务中重新实现它的部分;这基本上使用 CreateFileMapping(INVALID_HANDLE_NAME, ..., PAGE_READWRITE, ..., "Global\\my_service") 而不是 shm_open("/my_service", O_RDWR, O_CREAT)
然而,我有一些顾虑,特别是围绕这个页面文件支持的映射的生命周期。我在MSDN文档中没有找到这些问题的答案:
  • 映射是否会跨重启而持久存在?
  • 如果不是,当所有打开的句柄都关闭时,映射是否会消失?
  • 如果不是,是否有一种方法可以删除或清除映射?不需要在使用时进行。
如果它在重启后仍然存在,或者在没有引用的情况下消失,或者无法手动重置,则此方法对我毫无用处。
您能否验证或找出这些观点的错误,并/或推荐不同的方法?
如果有一个目录在重新启动时保证被清空,我可以把数据保存在一个临时文件中,但这仍然不是理想的:在某些系统负载下,我们遇到了文件打开/写入失败(很少发生,在0.01%以下的时间内,但仍然会发生),而这个功能将用于日志记录路径。我不想在这里引入更多的文件操作。
2个回答

1

共享内存映射不会在重新启动时保留,并且当所有句柄关闭时它将消失。内存映射对象是内核对象-它们总是在最后一个引用被明确关闭或包含引用的进程退出时被删除。

尝试使用RegCreateKeyEx创建具有REG_OPTION_VOLATILE的注册表键-当相应的hive卸载时,数据将不会被保存。这将在HKLM的系统关闭或HKCU的用户注销时发生。


感谢确认我的当前方法存在缺陷;我正在得出这个结论,但还没有进行测试。在HKLM中使用REG_OPTION_VOLATILE似乎很合适,我只需要解决一些内部注册表包装器的问题。 - ephemient

-1

听起来你可能需要序列化而不是共享内存?如果这确实适用于你的应用程序,那么你序列化的方式将取决于你使用的编程语言。如果你正在使用C++,可以查看boost::serialize。如果你使用的是C#,无疑会有很多序列化选项(就像Java一样)。


序列化不是问题,问题在于确保序列化数据的生命周期完全正确。 - ephemient

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接