使用Windows共享内存共享小数据

时间:2013-08-29 01:56:11

标签: c++ c winapi ipc shared-memory

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

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

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

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

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

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

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

是否有替代CreateFileMapping/OpenFileMappingMapViewOfFile技术更适合在进程之间共享非常少量的数据?或者我不担心什么?

2 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

答案 1 :(得分:1)

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