【问题标题】:Sharing small data using Windows shared memory使用 Windows 共享内存共享小数据
【发布时间】:2013-09-01 07:23:11
【问题描述】:

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

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

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

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

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

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

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

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

【问题讨论】:

  • 你在说多少个整数(大约)?
  • @JonathanPotter 粗略估计大约有 1000 个,所有名称都不同。每一个都将由一个或多个进程映射。
  • 如果您不想复制/实现自己的哈希系统,我所能想到的就是使用GlobalAddAtom() 为每个名称获取一个原子,将一个数据块维护为atom->indices 和另一个数据块来存储实际数据。这并不理想,因为它需要对原子映射进行线性搜索才能将原子转换为索引。
  • 我刚刚想到的另一个想法是创建一个使用SetProp()/GetProp() 维护整数的单例窗口。我不确定GetProp() 是否可以跨进程工作,但如果可以,您可以通过查找窗口句柄并调用GetProp() 直接读取整数。如果它不能跨进程工作,您仍然可以通过向窗口发送消息并让它返回GetProp() 调用的结果来执行此操作。唯一的缺点是性能,因为这肯定比直接访问共享内存要慢。
  • 实际上,如果您通过SendMessage() 进行操作,那么您甚至不需要使用窗口属性——您可以使用std::map

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


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 只要没有两个名称的哈希值相同。
  • @JonathanPotter,不是真的。哈希表将名称放入存储桶或列表指针的头部,然后按顺序搜索精确匹配。哈希表的要点是有一个 O(k) 哈希,然后对一个序列列表进行第二次 O(n/nr_bins) 搜索,该序列列表是 n 的一小部分。
  • 我知道哈希表是什么,但是您所描述的听起来不像是使用存储桶,而是依赖于名称和表中索引之间的直接 1:1 关系。我不确定你是否可以在 4Kb 中完成,但如果可以的话 - 太好了 :)
  • @JonathanPotter,即使哈希表必须超过两页(8k)并且整数在一页中,那仍然只有 12k,或者如果超过 1,000 个整数,甚至可以说(16k)。足够小,不会影响系统性能。
  • 我已经使用了这个想法,以及 Jonathan Potter 使用全局 ATOM 表的想法。这样,我可以使用提供的解决方案作为哈希表。共享整数数组的索引只是(Atom - MAXINTATOM)
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2012-12-11
    • 2013-05-20
    • 2011-09-09
    • 2014-10-08
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    相关资源
    最近更新 更多