我们的应用程序依赖于可加载为.so文件的外部第三方提供的配置(包括自定义驱动/决策功能)。
独立地,它使用大量共享内存与外部CGI模块协作,其中几乎保留了所有易失性状态,以便外部模块可以读取并在适用的情况下对其进行修改。
问题是CGI模块也需要来自.so的大量永久配置数据,主应用程序在两个内存区域之间执行大量完全不必要的复制以使数据可用。我们的想法是将整个共享对象加载到共享内存中,并使其直接可用于CGI。问题是:如何?
答案 0 :(得分:3)
使用共享内存时要记住的第一件事是,相同的物理内存可能会被映射到两个进程虚拟地址空间作为不同的地址。这意味着如果在数据结构中的任何地方使用指针,它们将导致问题。一切都必须使索引或偏移正常工作。要使用共享内存,您必须清除代码中的所有指针。
加载.so文件时,只加载.so文件代码的一个副本(因此称为共享对象)。
fork
也可能是你的朋友。大多数现代操作系统都实现了写时复制语义。这意味着当您fork
时,只有当一个进程写入给定数据段时,您的数据段才会被复制到单独的物理内存中。
答案 1 :(得分:2)
正如您所发现的那样,将实际C ++对象放置在共享内存中非常非常困难。我强烈建议你不要这样做 - 将需要在共享内存或内存映射文件中共享的数据放得更简单,并且可能更加健壮。
答案 2 :(得分:2)
我认为最简单的选择是使用内存映射文件,Neil已经提出了什么。如果此选项填充不好,则可以选择定义专用分配器。这是一篇关于它的好文章:Creating STL Containers in Shared Memory
还有出色的IonGaztañagaBoost.Interprocess图书馆shared_memory_object
和相关功能。 Ion为未来的TR提出了C ++标准化委员会的解决方案:Memory Mapped Files And Shared Memory For C++
可能表明值得考虑的解决方案。
答案 3 :(得分:0)
你需要实现对象的Serialization 序列化函数将您的对象转换为字节,然后您可以在SharedMemory中写入字节并让您的CGI模块将字节反序列化回对象。