在我看来,只有前 4 个变量(类型、型号、制造商和年份)属于配置文件。由于其他 3 个变量(温度、使用情况、状态)每隔几秒就会改变一次,它们实际上是应该保存在内存中的动态状态信息,您应该提供一个 API 以便检查这些状态信息。API 可能是,例如,通过客户端-服务器套接字连接,或通过共享内存。你可能会说,“我不能那样做,因为 [这样那样]”,所以我建议你用这样的推理更新你的问题。这样做可能会帮助您获得更多有用的答案。
由于更新问题中提供的额外信息而进行编辑...
我将要建议的内容适用于 Linux。我不知道其他操作系统。你可以做man shm_open
和man mmap
了解共享内存。共享内存段可以在进程重新启动后继续存在,并被备份到文件(在磁盘上),因此它可以在机器重新启动后继续存在。我(可能不正确)的理解是,大多数情况下,文件的内容将缓存在内核缓冲区中,虚拟内存会将这些内核缓冲区映射到进程的地址空间,因此读/写将是仅内存操作;因此您不会遭受频繁的磁盘 I/O。
为简单起见,我将假设每个设备都需要存储相同类型的动态信息,这可以用一个固定长度来表示struct
,例如:
struct DeviceData {
double temperature;
SomeEnum usage;
AnotherEnum status;
};
您可以拥有一个足够大的共享内存段来存储一个包含 100,000 个DeviceData
结构的数组。每个设备的静态配置文件将包含以下条目:
name="foo";
type="bar";
model="widget";
manufacture_year="2020";
shared_memory_id="/somename";
shared_memory_array_index="42";
静态配置文件中的最后两个条目指定进程应该连接到的共享内存段,以及它应该用来更新DeviceData
与进程关联的数组索引。
如果上述内容似乎适合您的需求,那么要处理的挑战是有效同步以读取/更新DeviceData
共享内存中的 a。一篇名为“具有乐观重试的可扩展读取器/写入器方案”的博客文章讨论了一种良好的基本方法。那篇博客文章使用 C# 来说明这个概念。如果您使用 C++,那么我建议您阅读Anthony Williams的C++ Concurrency in Action第 5 章( C++ 内存模型和原子类型的操作) 。顺便说一句,如果您可以使用填充来确保(完成和字段DeviceData
m_version1
m_version2
博客文章中使用的)与一个或多个缓存线的大小完全相同(在大多数 CPU 架构中,缓存线是 64 字节),那么您的实现不会受到错误共享的影响(这会不必要地降低性能)。
最后一步是避免将低级共享内存操作暴露给开发人员。因此,编写一个简单的包装 API,例如,四个操作:connect()
到和disconnect()
从共享内存段,以及readDeviceData()
和updateDeviceData()
。