4

我正在寻找有关在 Windows 上的共享内存段中存储少量数据(只有几个字节)的建议和建议。

现在,每当我们映射共享内存时,我们都会将映射大小四舍五入到最接近的 4KB,这样我们就会得到多个映射的页面。

mem_size = ((mem_size + 4095) / 4096) * 4096;

但是,我想映射足够的内存以在进程之间共享一个命名整数。或者更具体地说,进程之间有许多不同名称的整数。我正在查看大约一千个整数,它们都有不同的名称,每个都由一个或多个进程映射。

我不想将 4 个字节四舍五入到 4KB,因为这将是一个巨大的浪费。在创建了大约一千页之后,当我只需要一个时,我会使用大约一千页。

但我担心仅为 4 个字节创建命名内存段的开销。操作系统是否足够“合理”以尝试在可能的情况下将不同的映射安装到同一页面上?(我知道,没有保证)。或者这会很快爆发吗?

我曾考虑映射一大块内存,但仍然需要按名称引用各个整数。在共享内存中维护哈希表似乎只是在复制操作系统的工作。

是否有一种替代CreateFileMapping/OpenFileMapping技术MapViewOfFile更适合在进程之间共享非常少量的数据?还是我什么都不担心?

4

2 回答 2

4

你可以在 8K 中做到这一点。第一个 4k 块是整数名称及其在第二个 4k 块中的偏移量的二进制表(或哈希表)。添加新名称时,您将需要序列化,并且在检索名称/偏移量时,阻止该序列化。

在进程检索到其名称/偏移量后,它可以直接进入第二个块并避免任何序列化!这将是一个占用超过 90%(可能)时间的逻辑路径。因此,您的代码应该以最小的开销非常有效地运行。

第二个 4k 块将保存 1,000int秒(无论如何在 Windows 中!)。每个整数都不会影响其他整数,因此这种设计是“线程安全的”。但是,如果进程做了很多更新到这个公共文件的操作(其中很多是每个进程大约每 1ms 更新一次,因此两个进程总是争用写入文件),并且必须序列化整个文件(而不是隐含的,因为没有两个进程共享相同的整数名称)在就地更新时,您最终可能会遇到瓶颈。

以下链接: http: //msdn.microsoft.com/en-us/library/aa366801%28v=vs.85%29.aspx描述了如何更新共享内存。如果每个进程都有自己的整数“槽”,那么就不应该有任何争用。

我不认为名称树或哈希表会复制操作系统。

最后,这似乎是一个中等技能的项目,应该相对容易维护!

于 2013-08-29T02:09:32.680 回答
1

x86 处理器上的共享内存段不能小于 4096 字节。共享内存由处理器上的 mmu 处理,它将所有内容组织在 4096 字节的大页面中。

于 2013-08-29T02:10:23.947 回答