2009-12-23 47 views
8

我们需要多个程序来调用公共库中的函数。库函数访问并更新一个通用的全局内存。每个程序的函数调用都需要看到这个通用的全局内存。这是一个函数调用需要查看任何以前的函数调用的更新,即使从另一个程序调用。 出于兼容性的原因,我们对如何共享库暴露出的功能必须操作多个设计约束:实例化共享内存中的对象C++

  • 被全局声明的任何数据项(包括标准数据类型和对象)必须对所有主叫方可见不管代码正在运行的线程。
  • 在函数中本地声明的任何数据项只在该函数内可见。
  • 任何标准数据类型或任何类的实例可能出现在本地或全局或两者。

一个解决方案是将库的通用全局内存放在命名共享内存中。第一个库调用将创建指定的共享内存并对其进行初始化。随后的程序调用将获得共享内存的地址,并将其用作指向全局数据结构的指针。全局声明的对象实例需要在共享内存中动态分配,而本地声明的对象实例可以放在堆栈中或调用者线程的本地堆中。出现问题是因为全局内存中的初始化对象可以创建并指向分配(新)附加内存的子对象。这些新分配也需要在共享内存中,并由所有库呼叫者看到。另一个复杂因素是这些对象包含字符串,文件等,也可以用在调用程序中。在调用程序中声明时,对象的内存对于调用程序是本地的,不是共享的。所以对象的代码需要处理这两种情况。 在我们看来,解决方案将要求我们重写全局布局新的常规新操作符和删除操作符。我们找到了一个内存管理系统的设计,看起来可以工作,但我们还没有找到任何实际的实现。如果有人知道Nathan Myers的内存管理设计(http://www.cantrip.org/wave12.html?seenIEPage=1)的实现,我会很感激链接。或者,如果有人知道另一个可以动态分配对象的共享内存管理器,我也很想知道它。我检查了Boost库和我能找到的所有其他来源,但似乎没有做我们需要的东西。我们宁愿不必自己写一个。由于性能和健壮性非常重要,因此使用经过验证的代码会很好。提前感谢任何想法/帮助。

感谢您对ATL和OSSP库的建议。我现在正在检查它们,但是如果目标是Unix,恐怕ATL太温和了。

另一件事现在看起来很清楚。由于可以在执行过程中动态创建对象,因此内存管理方案必须能够分配额外的共享内存页面。现在开始看起来像一个全面的堆更换内存管理器。

+2

是不是创建服务器的问题的标准解决方案,哪些客户端应用程序可以使用?共享内存比共享内存要容易得多,这不太可能因为你给的原因而工作。 – 2009-12-23 15:50:16

+0

同意尼尔。 – wheaties 2009-12-23 15:54:16

+0

是的。重新设计应用程序将是解决问题的最简单方法。不幸的是,由于与其他组件相关的设计限制,我们没有这个选项。 – BillC 2009-12-23 23:04:37

回答

0

OSSP毫米 - 共享内存分配:

人3毫米

1
+1

正如我在帖子中提到的那样,我们查看了Boost库。不幸的是,它没有完成我们所需要的。不过,它引导我们获得了一些有希望的资源,例如我在帖子中提到的链接。 – BillC 2009-12-23 23:09:39

0

正如我相信你已经发现,这是一个非常复杂的问题,很难正确实施。从我的经验中得到一些提示。首先,你一定要使用信号量来同步对共享内存分配的访问。其次,多进程对共享对象的修改也需要通过信号量来保护。最后,在定义对象和数据结构时,您需要考虑共享内存区域开始时的偏移量而不是绝对指针值(通常可以将内存映射到每个附加进程中的不同地址,尽管你可以选择一个固定的映射地址,如果你需要)。把它放在一起是一个很难的部分。如果一个进程意外停止,基于共享内存的数据结构很容易被破坏,所以通常需要一些清理/恢复机制。

+0

你完全正确。问题很复杂,这就是为什么我们不想从头开始编写代码。 – BillC 2009-12-23 23:08:05

0

还研究互斥和信号量。当两个或两个以上的实体需要共享内存或数据时,需要有一个“交通信号”机制来限制只有一个用户的写访问。

+0

谢谢。我们知道这需要线程安全,并已实施互斥来控制访问。我们所面临的主要问题是如何确保某些对象以及它们实例化的任何对象在共享内存中分配,而同一对象的其他实例则在本地分配。 – BillC 2009-12-23 23:06:57

+0

混合过程 - 像你所描述的本地和共享内存似乎通常就像是一场灾难。定义更正式的进程间通信协议可能是更好的方法。 – 2009-12-27 01:16:16