2009-12-23 17 views
8

Tenemos una necesidad de múltiples programas para llamar funciones en una biblioteca común. Las funciones de la biblioteca acceden y actualizan una memoria global común. Las llamadas a funciones de cada programa necesitan ver esta memoria global común. Esa es una llamada de función que necesita ver las actualizaciones de cualquier llamada de función anterior, incluso si se llama desde otro programa. Por razones de compatibilidad tenemos varias restricciones de diseño sobre cómo las funciones expuestas por la biblioteca compartida deben operar:Creación de instancias de objetos en memoria compartida C++

  • Todos los elementos de datos (ambos tipos de datos estándar y objetos) que se declaran a nivel mundial debe ser visible para todas las llamadas sin tener en cuenta el hilo en el que se está ejecutando el código.
  • Todos los elementos de datos que se declaran localmente en una función solo son visibles dentro de esa función.
  • Cualquier tipo de datos estándar o una instancia de cualquier clase pueden aparecer localmente o globalmente o ambos.

Una solución es colocar la memoria global común de la biblioteca en la memoria compartida con nombre. La primera llamada a la biblioteca crearía la memoria compartida nombrada y la inicializaría. Las llamadas subsiguientes al programa obtendrían la dirección de la memoria compartida y la usarían como un puntero a la estructura de datos global. Las instancias de objetos declaradas globalmente deberían asignarse dinámicamente en la memoria compartida, mientras que las instancias de objetos declaradas localmente podrían colocarse en la pila o en el montón local de la cadena de llamadas. Los problemas surgen porque los objetos inicializados en la memoria global pueden crear y señalar subobjetos que asignan (nueva) memoria adicional. Estas nuevas asignaciones también deben estar en la memoria compartida y ser vistas por todas las personas que llaman a la biblioteca. Otra complicación es que estos objetos, que contienen cadenas, archivos, etc., también se pueden usar en el programa de llamada. Cuando se declara en el programa de llamada, la memoria del objeto es local para el programa de llamada, no compartida. Entonces, el código del objeto necesita manejar cualquier caso. Nos parece que la solución requerirá que anulemos la ubicación global de operadores nuevos, regulares nuevos y de eliminación. Encontramos un diseño para un sistema de administración de memoria que parece que funcionará, pero no hemos encontrado ninguna implementación real. Si alguien sabe de una implementación del diseño de administración de memoria de Nathan Myers (http://www.cantrip.org/wave12.html?seenIEPage=1) agradecería un enlace. Alternativamente, si alguien sabe de otro administrador de memoria compartida que se acomoda dinámicamente a la asignación de objetos, me gustaría saberlo también. Revisé las bibliotecas de Boost y todas las otras fuentes que puedo encontrar, pero parece que nada hace lo que necesitamos. Preferimos no tener que escribir uno nosotros mismos. Dado que el rendimiento y la robustez son importantes, sería bueno usar un código probado. Gracias de antemano por cualquier idea/ayuda.

Gracias por las sugerencias sobre las bibliotecas ATL y OSSP. Estoy revisándolos ahora aunque me temo que ATL es demasiado Wincentric si el objetivo resulta ser Unix.

Otra cosa ahora parece clara para nosotros. Dado que los objetos se pueden crear dinámicamente durante la ejecución, el esquema de administración de memoria debe poder asignar páginas adicionales de memoria compartida. Esto ahora está empezando a parecer un administrador de memoria de reemplazo de montón en toda regla.

+2

¿No es la solución canónica para este problema crear un servidor, que las aplicaciones cliente pueden usar? Mucho más fácil que futzing con la memoria compartida, que es poco probable que funcione por las razones que das. –

+0

De acuerdo con Neil. – wheaties

+0

Sí. Rediseñar la aplicación sería la forma más fácil de resolver el problema. Desafortunadamente, debido a restricciones de diseño debido a la compatibilidad con otros componentes, no tenemos esa opción. – BillC

Respuesta

0

OSSP mm - Asignación de memoria compartida:

man 3 mm

1

Tome un vistazo a boost.interprocess.

+1

Como mencioné en la publicación, miramos la biblioteca de Boost. Desafortunadamente no logró lo que necesitábamos. Sin embargo, nos lleva a algunos recursos prometedores, como el enlace que mencioné en la publicación. – BillC

0

Como estoy seguro que ha encontrado, este es un problema muy complejo y muy difícil de implementar correctamente. Algunos consejos de mis experiencias. Antes que nada, definitivamente querrás sincronizar el acceso a las asignaciones de memoria compartida usando semáforos. En segundo lugar, cualquier modificación a los objetos compartidos por procesos múltiples necesita ser protegida por semáforos también.Finalmente, debe pensar en términos de desplazamientos desde el inicio de la región de memoria compartida, en lugar de valores de puntero absolutos, al definir sus objetos y estructuras de datos (generalmente es posible mapear la memoria en una dirección diferente en cada proceso adjunto) , aunque puede elegir una dirección de mapeo fija si es necesario). Poner todo junto de una manera robusta es la parte difícil. Es fácil que las estructuras de datos basadas en la memoria compartida se corrompan si un proceso debe morir inesperadamente, por lo que normalmente se requiere algún mecanismo de limpieza/recuperación.

+0

Tienes razón. El problema es complejo y es por eso que no queremos tener que escribir el código desde cero. – BillC

0

También estudie mutexes y semáforos. Cuando dos o más entidades necesitan compartir memoria o datos, es necesario que haya un mecanismo de "señal de tráfico" para limitar el acceso de escritura a un solo usuario.

+0

Gracias. Entendemos que esto debe ser seguro para subprocesos y haber implementado mutexes para controlar el acceso. El problema principal que tenemos es cómo asegurar que algunos objetos se asignan en la memoria compartida, junto con cualquier objeto que instancian, mientras que otras instancias de los mismos objetos se asignan localmente. – BillC

+0

Proceso de mezcla: la memoria local y compartida, como la que describe, parece en general una receta para el desastre. Definir un protocolo de comunicación entre procesos más formal es probablemente un mejor enfoque. –

Cuestiones relacionadas