En esta página

Claves IPC nativas

Las clases QSharedMemory y QSystemSemaphore identifican su recurso utilizando un identificador de todo el sistema conocido como "clave". El valor de la clave de bajo nivel, así como el tipo de clave, se encapsulan en Qt utilizando la clase QNativeIpcKey. Esa clase también proporciona los medios adecuados para intercambiar la clave con otros procesos, mediante QNativeIpcKey::toString() y QNativeIpcKey::fromString().

Qt soporta actualmente tres backends distintos para esas dos clases, que coinciden con los valores disponibles en la enumeración QNativeIpcKey::Type.

  • Extensiones POSIX Realtime (IEEE 1003.1b, POSIX.1b)
  • X/Open System Interfaces (XSI) o System V (SVr4), aunque ahora también forman parte de POSIX
  • Primitivas de Windows

Como su nombre indica, las primitivas de Windows sólo están disponibles en el sistema operativo Windows, donde son el backend por defecto. Las otras dos suelen estar disponibles en sistemas operativos Unix. La siguiente tabla proporciona una visión general de la disponibilidad típica desde Qt 6.6:

Sistema operativoPOSIXSistema VWindows
Android
INTEGRIDAD
QNX
macOSNormalmente (1)
Otros SO de Apple
Otros sistemas Unix
WindowsRaramente (2)

Nota: 1 Las aplicaciones Sandboxed de macOS, que incluyen todas las aplicaciones distribuidas a través de la App Store de Apple, no pueden utilizar objetos System V.

Nota: 2 Algunos tiempos de ejecución de C compatibles con GCC en Windows proporcionan soporte de memoria compartida compatible con POSIX, pero esto es raro. Siempre está ausente con el compilador de Microsoft.

Para determinar si un determinado tipo de clave está soportado, las aplicaciones deberían llamar a QSharedMemory::isKeyTypeSupported() y QSystemSemaphore::isKeyTypeSupported().

QNativeIpcKey también proporciona soporte para compatibilidad con aplicaciones Qt anteriores a su introducción. Las siguientes secciones detallan las limitaciones de los backends, el contenido de las propias claves de cadena y la compatibilidad.

Formato de clave seguro multiplataforma

QNativeIpcKey::setNativeKey() y QNativeIpcKey::nativeKey() gestionan la clave nativa de bajo nivel, que puede utilizarse con las API nativas y compartirse con otros procesos que no sean Qt (véase más adelante la API). Este formato no suele ser multiplataforma, por lo que tanto QSharedMemory como QSystemSemaphore proporcionan una función para traducir una cadena de identificador multiplataforma a la clave nativa: QSharedMemory::platformSafeKey() y QSystemSemaphore::platformSafeKey().

La longitud de la clave multiplataforma en la mayoría de las plataformas es la misma que la de un nombre de archivo, pero está severamente limitada en las plataformas Apple a sólo 30 bytes utilizables (tenga en cuenta la codificación UTF-8 si utiliza caracteres fuera del rango US-ASCII). El formato de la clave también es similar al de un componente de ruta de archivo, lo que significa que no debe contener ningún carácter no permitido en los nombres de archivo, en particular los que separan los componentes de ruta (barra oblicua y barra invertida), con la excepción de las aplicaciones sandboxed en los sistemas operativos Apple. Los siguientes son buenos ejemplos de claves multiplataforma: "myapp", "org.example.myapp", "org.example.myapp-12345". Tenga en cuenta que es responsabilidad del usuario evitar claves demasiado grandes y asegurarse de que la clave contiene caracteres legales en la plataforma correspondiente. Qt truncará silenciosamente las claves demasiado largas.

Limitaciones del sandbox de Apple: si la aplicación se ejecuta dentro de un sandbox en un sistema operativo Apple, la clave debe estar en un formato muy específico: <application group identifier>/<custom identifier>. El sandboxing está implícito para todas las aplicaciones distribuidas a través de la App Store de Apple. Consulte la documentación de Apple aquí y aquí para obtener más información, incluido cómo obtener el identificador de grupo de la aplicación.

Formato de la clave nativa

Esta sección detalla el formato de las claves nativas de los backends soportados.

POSIX en tiempo real

Las claves nativas se parecen a los nombres de archivo y pueden contener cualquier carácter que contengan los nombres de archivo, excepto una barra. POSIX requiere que el primer carácter del nombre de la clave sea una barra y deja sin determinar si se permiten barras adicionales. En la mayoría de los sistemas operativos, la longitud de la clave es la misma que la de un nombre de fichero, pero está limitada a 32 caracteres en los sistemas operativos Apple (esto incluye la primera barra y el nulo de terminación, por lo que sólo son posibles 30 caracteres utilizables).

Los siguientes son buenos ejemplos de claves POSIX nativas: "/myapp", "/org.example.myapp", "/org.example.myapp-12345".

QSharedMemory::platformSafeKey() y QSystemSemaphore::platformSafeKey() simplemente anteponen la barra. En los sistemas operativos Apple, también truncan el resultado al tamaño disponible.

Windows

Los tipos de clave de Windows son nombres de objetos del kernel NT y pueden tener hasta MAX_PATH (260) caracteres de longitud. Parecen rutas relativas (es decir, no empiezan con una barra invertida ni con una letra de unidad), pero a diferencia de los nombres de archivo en Windows, distinguen entre mayúsculas y minúsculas.

Los siguientes son buenos ejemplos de claves nativas de Windows: "myapp", "org.ejemplo.myapp", "org.ejemplo.myapp-12345".

QSharedMemory::platformSafeKey() y QSystemSemaphore::platformSafeKey() insertan un prefijo para desambiguar la memoria compartida y los semáforos del sistema, respectivamente.

Interfaces X/Sistema Abierto (XSI) / Sistema V

Las claves del Sistema V toman la forma del nombre de un fichero del sistema y, por tanto, tienen exactamente las mismas limitaciones que las rutas de los ficheros. Tanto QSharedMemory como QSystemSemaphore crearán este archivo si no existe al crear el objeto. Si la eliminación automática está desactivada, también puede ser compartida entre QSharedMemory y QSystemSemaphore sin conflicto y puede ser cualquier archivo existente (por ejemplo, puede ser el propio ejecutable del proceso, véase QCoreApplication::applicationFilePath()). La ruta debe ser absoluta para evitar errores debidos a diferentes directorios actuales.

QSharedMemory::platformSafeKey() y QSystemSemaphore::platformSafeKey() siempre devuelven una ruta absoluta. Si la entrada ya era absoluta, devolverán su entrada sin cambios. En caso contrario, añadirán una ruta adecuada en la que la aplicación tenga permiso para crear ficheros.

Propiedad

Los objetos de memoria compartida y semáforo del sistema necesitan ser creados antes de su uso, lo que se consigue con QSharedMemory::create() o pasando QSystemSemaphore::Create al constructor, respectivamente.

En sistemas Unix, las clases Qt que crearon el objeto serán responsables de limpiar el objeto en cuestión. Por lo tanto, si la aplicación con ese objeto C++ sale sin limpiar (un crash, qFatal(), etc.), el objeto puede quedar atrás. Si eso ocurre, las aplicaciones pueden fallar al crear el objeto de nuevo y en su lugar deben adjuntarlo a uno existente. Por ejemplo, para QSharedMemory:

if (!shm.create(4096) && shm.error() == QSharedMemory::AlreadyExists)
    shm.attach();

Volver a adjuntar a un QSystemSemaphore es probablemente imprudente, ya que el contador de tokens en él está probablemente en un estado desconocido y por lo tanto puede conducir a bloqueos.

POSIX Realtime

La propiedad de objetos POSIX Realtime sigue el patrón de los ficheros, en el sentido de que existen independientemente de cualquier proceso que los use o no. Qt es incapaz de determinar si el objeto está todavía en uso, por lo que la auto-eliminación lo eliminará incluso entonces, lo que hará que adjuntar al mismo objeto sea imposible pero, por lo demás, no afectará a los adjuntos existentes.

Antes de Qt 6.6, Qt nunca limpiaba objetos POSIX Realtime, excepto en QNX.

Interfaces X/Sistema Abierto (XSI) / Sistema V

Hay dos recursos gestionados por las clases Qt: el archivo al que se refiere la clave y el objeto en sí. QSharedMemory gestiona el objeto de forma cooperativa: el último adjunto es responsable de eliminar el objeto en sí y después de eliminar el archivo de claves. QSystemSemaphore eliminará el objeto si y sólo si se le pasó QSystemSemaphore::Create; además, si creó el archivo de claves, también lo eliminará.

Desde Qt 6.6, es posible pedir a cualquiera de las clases que no limpie.

Windows

El sistema operativo es el propietario del objeto y lo limpiará después de que se cierre el último manejador del objeto.

Interoperabilidad con aplicaciones Qt antiguas

La clase QNativeIpcKey se introdujo en Qt 6.6. Antes de esta versión, los backends QSharedMemory y QSystemSemaphore se determinaban en el momento de la propia compilación de Qt. Para sistemas Windows, siempre era el backend de Windows. Para sistemas Unix, por defecto era el backend System V si el script de configuración determinaba que estaba disponible. Si no estaba disponible, volvía al POSIX. El backend POSIX podía seleccionarse explícitamente usando la opción -feature-ipc_posix del script de configuración de Qt; si se activaba, se definía la macro QT_POSIX_IPC.

Qt 6.6 mantiene la opción del script configure pero ya no controla la disponibilidad de los backends. En su lugar, cambia lo que QNativeIpcKey::legacyDefaultTypeForOs() devolverá. Las aplicaciones que necesiten mantener la compatibilidad deben utilizar exclusivamente este tipo de clave para garantizar la interoperabilidad.

La API tanto en QSharedMemory como en QSystemSemaphore tenía el concepto de clave multiplataforma, que ahora está obsoleto en favor del uso de QSharedMemory::legacyNativeKey() y QSystemSemaphore::legacyNativeKey(). Estas dos funciones producen la misma clave nativa que las funciones obsoletas en versiones anteriores. Si el código antiguo era por ejemplo:

QSharedMemory shm("org.example.myapplication");
QSystemSemaphore sem("org.example.myapplication");

Se puede actualizar para que sea:

QSharedMemory shm(QSharedMemory::legacyNativeKey("org.example.myapplication"));
QSystemSemaphore sem(QSystemSemaphore::legacyNativeKey("org.example.myapplication"));

Si las dos aplicaciones intercambiaban claves nativas, no es necesario actualizar código como:

QSharedMemory shm;
shm.setNativeKey(key);

Aunque si la aplicación antigua sí aceptaba una clave nativa, la nueva puede optar por utilizar platformSafeKey() con un segundo argumento de QNativeIpcKey::legacyDefaultTypeForOs().

Interfaces X/Sistema Abierto (XSI) / Sistema V

Nunca utilice archivos existentes para claves QSharedMemory, ya que la antigua aplicación Qt puede intentar eliminarla. En su lugar, deje que QSharedMemory lo cree.

Interoperabilidad con aplicaciones que no sean Qt

La interoperabilidad con aplicaciones que no sean Qt es posible, con algunas limitaciones:

  • La creación de segmentos de memoria compartida no debe correr
  • QSharedMemory el soporte para bloquear el segmento no está disponible

La comunicación con aplicaciones que no sean Qt debe realizarse siempre a través de la clave nativa.

QSharedMemory siempre asigna todo el segmento a la memoria. La aplicación no-Qt puede elegir asignar sólo un subconjunto a la memoria, sin efectos negativos.

POSIX en tiempo real

La memoria compartida POSIX puede abrirse usando shm_open() y los semáforos del sistema POSIX pueden abrirse usando sem_open().

Ambas funciones toman un parámetro name que es el resultado de QNativeIpcKey::nativeKey(), codificado para nombres de archivo usando QFile::encodeName() / QFile::decodeName().

Windows

Los objetos de memoria compartida de Windows pueden abrirse utilizando CreateFileMappingW y los objetos semáforo del sistema de Windows pueden abrirse utilizando CreateSemaphoreW. A pesar de que el nombre de ambas funciones empieza por "Create", pueden adjuntarse a objetos existentes.

El parámetro lpName de esas funciones es el resultado de QNativeIpcKey::nativeKey(), sin transformación.

Si la aplicación externa utiliza la versión no Unicode de esas funciones (que terminan en "A"), el nombre puede convertirse a y desde 8 bits utilizando QString.

X/Open System Interfaces (XSI) / Sistema V

La memoria compartida del Sistema V puede obtenerse utilizando shmget() y los semáforos del sistema del Sistema V pueden obtenerse utilizando semget().

El parámetro key de cualquiera de esas funciones es el resultado de la función ftok( ) cuando se le pasa el nombre de fichero obtenido de QNativeIpcKey::nativeKey() con un id de 81 o 0x51 (la letra ASCII mayúscula 'Q').

Los objetos semáforo del Sistema V pueden contener múltiples semáforos, pero QSystemSemaphore sólo utiliza el primero (número 0 para sem_num).

Tanto QSharedMemory como QSystemSemaphore eliminan por defecto el objeto utilizando la operación IPC_RMID a shmctl() y semctl() respectivamente si son el último adjunto.

© 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.