En informática , la memoria compartida es la memoria a la que pueden acceder simultáneamente varios programas con la intención de proporcionar comunicación entre ellos o evitar copias redundantes. La memoria compartida es un medio eficaz para pasar datos entre programas. Dependiendo del contexto, los programas pueden ejecutarse en un solo procesador o en varios procesadores separados.
El uso de memoria para la comunicación dentro de un único programa, por ejemplo, entre sus múltiples subprocesos , también se denomina memoria compartida.
En hardware informático, 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 datos y la comunicación entre procesadores puede ser tan rápida como los accesos a la 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 memoria caché , 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 los cuellos 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 administración de memoria (MMU) de la CPU y la unidad de administración de memoria de entrada-salida (IOMMU) de La GPU tiene que 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 de comunicación muy rápida (a diferencia de otros mecanismos de IPC como canalizaciones con nombre , sockets de dominio Unix o CORBA ). Por otro lado, es menos escalable, ya que, por ejemplo, los procesos de comunicación deben ejecutarse en la misma máquina (de otros métodos IPC, sólo los sockets de dominio de Internet, no los sockets de dominio de Unix, pueden utilizar una red informática ), y se debe tener cuidado. Se toman medidas para evitar problemas si los procesos que comparten memoria se ejecutan en CPU separadas y la arquitectura subyacente no es coherente con la caché .
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 resuelve de manera diferente allí) se duplican, generalmente con un mecanismo conocido como copia en escritura que de forma transparente copia la página cuando se intenta escribir y luego permite que la escritura se realice correctamente en la copia privada.
En comparación con los sistemas operativos con múltiples espacios de direcciones, compartir memoria (especialmente procedimientos compartidos 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 usar memoria compartida, POSIX Shared Memory . Esto 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
, shmctl
y . [4] [5] Unix System V también proporciona una API para memoria compartida. Esto usa shmget de sys/shm.h. Los sistemas BSD proporcionan "memoria asignada anónima" que puede ser utilizada por varios procesos.shmdt
shmget
La memoria compartida creada por shm_open
es persistente. Permanece en el sistema hasta que un proceso lo elimina explícitamente. Esto tiene el inconveniente de que 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 una asignación, lo que permite utilizar el contenido del archivo como memoria compartida.
Las distribuciones de 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 mundial (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 de forma predeterminada. El soporte para este tipo de disco RAM es completamente opcional dentro del archivo de configuración del kernel . [7]
En Windows, se pueden usar funciones CreateFileMapping
y MapViewOfFile
para asignar una región de un archivo a 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 Boost.Interprocess C++ [9] y Qt proporciona la clase QSharedMemory. [10]
Para 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 efectos similares. 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 Unix System V.