En informática , la memoria compartida es una memoria a la que pueden acceder varios programas simultáneamente con el fin de facilitar la comunicación entre ellos o evitar copias redundantes. La memoria compartida es un medio eficiente para pasar datos entre programas. Según el contexto, los programas pueden ejecutarse en un solo procesador o en varios procesadores independientes.
El uso de la memoria para la comunicación dentro de un solo programa, por ejemplo, entre sus múltiples subprocesos , también se conoce como memoria compartida.
En hardware de computadoras, la memoria compartida se refiere a un bloque (normalmente grande) de memoria de acceso aleatorio (RAM) al que pueden acceder varias unidades centrales de procesamiento (CPU) diferentes en un sistema informático multiprocesador .
Los sistemas de memoria compartida pueden utilizar: [1]
Un sistema de memoria compartida es relativamente fácil de programar, ya que todos los procesadores comparten una única vista de los datos y la comunicación entre procesadores puede ser tan rápida como los accesos de memoria a la misma ubicación. El problema con los sistemas de memoria compartida es que muchas CPU necesitan un acceso rápido a la memoria y probablemente almacenarán en caché la memoria , lo que tiene dos complicaciones:
Se pueden utilizar tecnologías como conmutadores de barra transversal , redes Omega , HyperTransport o bus frontal para amortiguar los efectos de cuello de botella.
En el caso de una arquitectura de sistema heterogénea (arquitectura de procesador que integra diferentes tipos de procesadores, como CPU y GPU , con memoria compartida), la unidad de gestión de memoria (MMU) de la CPU y la unidad de gestión de memoria de entrada-salida (IOMMU) de la GPU deben compartir ciertas características, como un espacio de direcciones común.
Las alternativas a la memoria compartida son la memoria distribuida y la memoria compartida distribuida , cada una con un conjunto similar de problemas.
En el software de computadora, la memoria compartida es
Dado que ambos procesos pueden acceder al área de memoria compartida como la memoria de trabajo normal, esta es una forma muy rápida de comunicación (a diferencia de otros mecanismos de IPC como las canalizaciones con nombre , los sockets de dominio Unix o CORBA ). Por otro lado, es menos escalable, ya que, por ejemplo, los procesos que se comunican deben estar ejecutándose en la misma máquina (de otros métodos de IPC, solo los sockets de dominio de Internet, no los sockets de dominio Unix, pueden usar una red de computadoras ), y se debe tener cuidado para evitar problemas si los procesos que comparten memoria se ejecutan en CPU separadas y la arquitectura subyacente no es coherente con la caché .
El IPC por memoria compartida se utiliza, por ejemplo, para transferir imágenes entre la aplicación y el servidor X en sistemas Unix, o dentro del objeto IStream devuelto por CoMarshalInterThreadInterfaceInStream en las bibliotecas COM en Windows .
Las bibliotecas dinámicas generalmente se guardan en la memoria una vez y se asignan a múltiples procesos, y solo las páginas que tuvieron que personalizarse para el proceso individual (porque un símbolo se resolvió de manera diferente allí) se duplican, generalmente con un mecanismo conocido como copia en escritura que copia de manera transparente la página cuando se intenta una escritura y luego permite que la escritura tenga éxito en la copia privada.
En comparación con los sistemas operativos con múltiples espacios de direcciones, compartir memoria (especialmente procedimientos de compartición o estructuras basadas en punteros) es más simple en los sistemas operativos con un solo espacio de direcciones . [2]
POSIX proporciona una API estandarizada para el uso de memoria compartida, POSIX Shared Memory . Esta utiliza la función shm_open
de sys/mman.h. [3] La comunicación entre procesos POSIX (parte de la extensión POSIX:XSI) incluye las funciones de memoria compartida shmat
, y shmctl
. [4] [5] Unix System V también proporciona una API para memoria compartida. Esta utiliza shmget de sys / shm.h. Los sistemas BSD proporcionan "memoria mapeada anónima" que pueden utilizar varios procesos.shmdt
shmget
La memoria compartida creada por shm_open
es persistente. Permanece en el sistema hasta que un proceso la elimine explícitamente. Esto tiene un inconveniente: si el proceso falla y no logra limpiar la memoria compartida, permanecerá hasta que se apague el sistema; esa limitación no está presente en una implementación específica de Android denominada ashmem
. [6]
POSIX también proporciona la mmap
API para mapear archivos en la memoria; se puede compartir un mapeo, lo que permite que el contenido del archivo se use como memoria compartida.
Las distribuciones Linux basadas en el kernel 2.6 y posteriores ofrecen /dev/shm como memoria compartida en forma de disco RAM , más específicamente como un directorio de escritura global (un directorio en el que cada usuario del sistema puede crear archivos) que se almacena en memoria. Tanto las distribuciones basadas en RedHat como en Debian lo incluyen por defecto. El soporte para este tipo de disco RAM es completamente opcional dentro del archivo de configuración del kernel . [7]
En Windows, se pueden utilizar funciones CreateFileMapping
y MapViewOfFile
para mapear una región de un archivo en la memoria en múltiples procesos. [8]
Algunas bibliotecas de C++ proporcionan un acceso portátil y orientado a objetos a la funcionalidad de memoria compartida. Por ejemplo, Boost contiene la biblioteca C++ Boost.Interprocess [9] y Qt proporciona la clase QSharedMemory. [10]
En el caso de los lenguajes de programación con enlaces POSIX (por ejemplo, C/C++), se pueden crear y acceder a regiones de memoria compartida llamando a las funciones proporcionadas por el sistema operativo. Otros lenguajes de programación pueden tener sus propias formas de utilizar estas funciones operativas para lograr un efecto similar. Por ejemplo, PHP proporciona una API para crear memoria compartida, similar a las funciones POSIX . [11]
La comunicación entre procesos POSIX (IPC) es parte de la extensión POSIX:XSI y tiene su origen en la comunicación entre procesos de Unix System V.