在共享内存中实例化对象

时间:2021-07-01 13:24:10

We have a need for multiple programs to call functions in a common library. The library functions access and update a common global memory. Each program’s function calls need to see this common global memory. That is one function call needs to see the updates of any prior function call even if called from another program. For compatibility reasons we have several design constraints on how the functions exposed by the shared library must operate:

我们需要多个程序来调用公共库中的函数。库函数访问并更新一个通用的全局内存。每个程序的函数调用都需要查看这个通用全局内存。这是一个函数调用需要查看任何先前的函数调用的更新,即使是从另一个程序调用的。出于兼容性的原因,我们对共享库公开的功能必须如何操作有几个设计限制:

  • Any data items (both standard data types and objects) that are declared globally must be visible to all callers regardless of the thread in which the code is running.
  • 全局声明的任何数据项(包括标准数据类型和对象)必须对所有调用者可见,而不考虑代码运行的线程。
  • Any data items that are declared locally in a function are only visible inside that function.
  • 函数中本地声明的任何数据项仅在该函数中可见。
  • Any standard data type or an instance of any class may appear either locally or globally or both.
  • 任何标准的数据类型或任何类的实例都可能出现在本地或全局或两者中。

One solution is to put the library’s common global memory in named shared memory. The first library call would create the named shared memory and initialize it. Subsequent program calls would get the address of the shared memory and use it as a pointer to the global data structure. Object instances declared globally would need to be dynamically allocated in shared memory while object instances declared locally could be placed on the stack or in the local heap of the caller thread. Problems arise because initialized objects in the global memory can create and point to sub-objects which allocate (new) additional memory. These new allocations also need to be in the shared memory and seen by all library callers. Another complication is these objects, which contain strings, files, etc., can also be used in the calling program. When declared in the calling program, the object’s memory is local to the calling program, not shared. So the object’s code needs to handle either case. It appears to us that the solution will require that we override the global placement new, regular new and delete operators. We found a design for a memory management system that looks like it will work but we haven’t found any actual implementations. If anyone knows of an implementation of Nathan Myers’ memory management design (http://www.cantrip.org/wave12.html?seenIEPage=1) I would appreciate a link to it. Alternatively if anyone knows of another shared memory manager that accommodates dynamically allocating objects I would love to know about it as well. I've checked the Boost libraries and all the other sources I can find but nothing seems to do what we need. We prefer not to have to write one ourselves. Since performance and robustness are important it would be nice to use proven code. Thanks in advance for any ideas/help.

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

Thanks for the suggestions about the ATL and OSSP libraries. I am checking them out now although I'm afraid ATL is too Wincentric if are target turns out to be Unix.

感谢您对ATL和OSSP库的建议。我现在正在检查它们,尽管我担心如果目标是Unix的话,它也太过以中心为中心。

One other thing now seems clear to us. Since objects can be dynamically created during execution, the memory management scheme must be able to allocate additional pages of shared memory. This is now starting to look like a full-blown heap replacement memory manager.

还有一件事我们现在很清楚。由于对象可以在执行期间动态创建,因此内存管理方案必须能够分配额外的共享内存页。现在,这看起来就像一个完整的堆替换内存管理器。

4 个解决方案

#1


1  

Take a look at boost.interprocess.

看看boost.interprocess。

#2


0  

OSSP mm - Shared Memory Allocation:

OSSP mm -共享内存分配:

man 3 mm

人3毫米

#3


0  

As I'm sure you have found, this is a very complex problem, and very difficult to correctly implement. A few tips from my experiences. First of all, you'll definitely want to synchronize access to the shared memory allocations using semaphores. Secondly, any modifications to the shared objects by multiple processes need to be protected by semaphores as well. Finally, you need to think in terms of offsets from the start of the shared memory region, rather than absolute pointer values, when defining your objects and data structures (it's generally possible for the memory to be mapped at a different address in each attached process, although you can choose a fixed mapping address if you need to). Putting it all together in a robust manner is the hard part. It's easy for shared memory based data structures to become corrupted if a process should unexpectedly die, so some cleanup / recovery mechanism is usually required.

我相信您已经发现,这是一个非常复杂的问题,很难正确实现。以下是我的一些经验。首先,您肯定希望使用信号量同步对共享内存分配的访问。其次,多个进程对共享对象的任何修改也需要信号量的保护。最后,您需要考虑补偿从共享内存区域的开始,而不是绝对的指针值,当定义对象和数据结构(通常有可能内存映射在一个不同的地址在每个附加的过程,虽然你可以选择一个固定的映射地址如果你需要)。以一种积极的方式把所有的事情放在一起是困难的部分。如果进程意外死亡,共享内存的数据结构很容易损坏,因此通常需要一些清理/恢复机制。

#4


0  

Also study mutexes and semaphores. When two or more entities need to share memory or data, there needs to be a "traffic signal" mechanism to limit write access to only one user.

也研究互斥和信号量。当两个或多个实体需要共享内存或数据时,需要有一个“流量信号”机制来限制对一个用户的写访问。

#1


1  

Take a look at boost.interprocess.

看看boost.interprocess。

#2


0  

OSSP mm - Shared Memory Allocation:

OSSP mm -共享内存分配:

man 3 mm

人3毫米

#3


0  

As I'm sure you have found, this is a very complex problem, and very difficult to correctly implement. A few tips from my experiences. First of all, you'll definitely want to synchronize access to the shared memory allocations using semaphores. Secondly, any modifications to the shared objects by multiple processes need to be protected by semaphores as well. Finally, you need to think in terms of offsets from the start of the shared memory region, rather than absolute pointer values, when defining your objects and data structures (it's generally possible for the memory to be mapped at a different address in each attached process, although you can choose a fixed mapping address if you need to). Putting it all together in a robust manner is the hard part. It's easy for shared memory based data structures to become corrupted if a process should unexpectedly die, so some cleanup / recovery mechanism is usually required.

我相信您已经发现,这是一个非常复杂的问题,很难正确实现。以下是我的一些经验。首先,您肯定希望使用信号量同步对共享内存分配的访问。其次,多个进程对共享对象的任何修改也需要信号量的保护。最后,您需要考虑补偿从共享内存区域的开始,而不是绝对的指针值,当定义对象和数据结构(通常有可能内存映射在一个不同的地址在每个附加的过程,虽然你可以选择一个固定的映射地址如果你需要)。以一种积极的方式把所有的事情放在一起是困难的部分。如果进程意外死亡,共享内存的数据结构很容易损坏,因此通常需要一些清理/恢复机制。

#4


0  

Also study mutexes and semaphores. When two or more entities need to share memory or data, there needs to be a "traffic signal" mechanism to limit write access to only one user.

也研究互斥和信号量。当两个或多个实体需要共享内存或数据时,需要有一个“流量信号”机制来限制对一个用户的写访问。