En esta página

Memoria Compartida

Qt proporciona dos técnicas para compartir memoria con otros procesos en el mismo sistema: QSharedMemory y archivos mapeados en memoria usando QFile. La memoria que se comparte con otros procesos a menudo se denomina "segmento", y aunque en el pasado puede haber sido implementada como segmentos específicos en procesadores con modelos de memoria segmentada, este no es el caso en ningún sistema operativo moderno. Los segmentos de memoria compartida son simplemente regiones de memoria que el sistema operativo asegurará que estén disponibles para todos los procesos que participen.

Nota: La dirección en la que se encuentra el segmento en memoria será casi siempre diferente para cada proceso que participe en la compartición. Por lo tanto, las aplicaciones deben tener cuidado de compartir sólo datos independientes de la posición, tales como tipos primitivos C++ o matrices de tales tipos.

Compartir memoria usando QSharedMemory

QSharedMemory proporciona una API simple para crear un segmento de memoria compartida de un tamaño dado o adjuntar a uno que fue creado por otro proceso. Además, proporciona un par de métodos para lock y unlock todo el segmento, utilizando un QSystemSemaphore interno.

Los segmentos de memoria compartida y los semáforos del sistema se identifican globalmente en el sistema a través de una "clave", que en Qt está representada por la clase QNativeIpcKey. Adicionalmente, dependiendo del SO, Qt puede soportar múltiples backends diferentes para compartir memoria; ver la documentación Native IPC Keys para más información y limitaciones.

QSharedMemory está diseñado para compartir memoria sólo dentro del mismo nivel de privilegios (es decir, no con otros procesos que no sean de confianza, como los iniciados por otros usuarios). Para los backends que lo soporten, QSharedMemory creará segmentos de tal forma que sólo los procesos con el mismo nivel de privilegio puedan adjuntarlos.

Compartir memoria mediante archivos asignados a memoria

La mayoría de los archivos se pueden mapear a memoria utilizando QFile::map() y, si no se especifica la opción MapPrivateOption, cualquier escritura en el segmento mapeado será observada por todos los demás procesos que hayan mapeado el mismo archivo. Las excepciones a los archivos que se pueden asignar a la memoria incluyen los archivos remotos que se encuentran en recursos compartidos de red o los ubicados en determinados sistemas de archivos. Incluso si el sistema operativo permite mapear archivos remotos a la memoria, las operaciones de E/S sobre el archivo probablemente se almacenarán en caché y se retrasarán, haciendo imposible la compartición real de memoria.

Esta solución tiene las grandes ventajas de ser independiente de cualquier API backend y de ser más sencilla de interoperar con aplicaciones que no sean Qt. Dado que QTemporaryFile es un QFile, las aplicaciones pueden utilizar esa clase para conseguir la semántica de limpieza y para crear también segmentos de memoria compartida únicos.

Para lograr el bloqueo del segmento de memoria compartida, las aplicaciones necesitarán desplegar sus propios mecanismos. Una forma puede ser utilizar QLockFile. Otra solución menos costosa es utilizar QAtomicInteger o std::atomic en un desplazamiento predeterminado en el propio segmento. Las primitivas de bloqueo de nivel superior pueden estar disponibles en algunos sistemas operativos; por ejemplo, en Linux, las aplicaciones pueden establecer la bandera "pshared" en el atributo mutex pasado a pthread_mutex_create() para indicar que el mutex reside en un segmento de memoria compartida.

Ten en cuenta que el sistema operativo probablemente intentará almacenar de forma permanente cualquier escritura realizada en la memoria compartida. Esto puede ser deseado o puede suponer una penalización de rendimiento si el archivo en sí estaba destinado a ser temporal. En ese caso, las aplicaciones deben localizar un sistema de archivos respaldado por RAM, como tmpfs en Linux (ver QStorageInfo::fileSystemType()), o pasar una bandera a la función nativa de apertura de archivos para informar al sistema operativo que evite comprometer el contenido al almacenamiento.

Es posible utilizar memoria compartida respaldada por archivos para comunicarse con procesos no confiables, en cuyo caso la aplicación debe tener mucho cuidado. Los archivos pueden truncarse/retrocederse y hacer que las aplicaciones que accedan a la memoria más allá del tamaño del archivo se bloqueen.

Consejos de Linux sobre archivos mapeados en memoria

En los sistemas Linux modernos, aunque el directorio /tmp es a menudo un punto de montaje de tmpfs, no es un requisito. Sin embargo, se requiere que el directorio /dev/shm sea un tmpfs y existe con el propósito de compartir memoria. Tenga en cuenta que puede leerse y escribirse en todo el mundo (como /tmp y /var/tmp), por lo que las aplicaciones deben tener cuidado con el contenido que se revela allí. Otra alternativa es usar el XDG Runtime Directory (ver QStandardPaths::writableLocation() y QStandardPaths::RuntimeLocation), que en sistemas Linux que usan systemd es un tmpfs específico del usuario.

Una solución aún más segura es crear un "memfd" usando memfd_create(2) y usar la comunicación entre procesos para pasar el descriptor de fichero, como QDBusUnixFileDescriptor o dejando que el proceso hijo de un QProcess lo herede. Los "memfds" también pueden sellarse para que no se encojan, por lo que es seguro utilizarlos cuando se comunican con procesos con un nivel de privilegios diferente.

Consejos de FreeBSD sobre ficheros mapeados en memoria

FreeBSD también tiene memfd_create(2) y puede pasar descriptores de fichero a otros procesos usando las mismas técnicas que Linux. No tiene sistemas de ficheros temporales montados por defecto.

Sugerencias de Windows sobre archivos mapeados en memoria

En Windows, la aplicación puede solicitar al sistema operativo que evite guardar el contenido del archivo en almacenamiento permanente. Esta petición se realiza pasando la bandera FILE_ATTRIBUTE_TEMPORARY en el parámetro dwFlagsAndAttributes a la función Win32 CreateFile, la bandera _O_SHORT_LIVED a la función de bajo nivel _open(), o incluyendo el modificador "T" a la función en tiempo de ejecución C fopen().

También existe una bandera para informar al sistema operativo de que elimine el archivo cuando se cierre el último manejador del mismo (FILE_FLAG_DELETE_ON_CLOSE, _O_TEMPORARY, y el modificador "D"), pero tenga en cuenta que todos los procesos que intenten abrir el archivo deben estar de acuerdo en utilizar o no esta bandera. Un desajuste probablemente causará una violación de compartición y un fallo al abrir el archivo.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.