Clés IPC natives
Les classes ` QSharedMemory ` et ` QSystemSemaphore ` identifient leurs ressources à l’aide d’un identifiant valable à l’échelle du système, appelé « clé ». La valeur de la clé de bas niveau ainsi que son type sont encapsulés dans Qt à l’aide de la classe ` QNativeIpcKey `. Cette classe fournit également les moyens appropriés pour échanger la clé avec d’autres processus, via les méthodes ` QNativeIpcKey::toString()` et ` QNativeIpcKey::fromString()`.
Qt prend actuellement en charge trois backends distincts pour ces deux classes, qui correspondent aux valeurs disponibles dans l’énumération QNativeIpcKey::Type.
- Extensions temps réel POSIX (IEEE 1003.1b, POSIX.1b)
- Interfaces système X/Open (XSI) ou System V (SVr4), bien qu’elles fassent désormais également partie de POSIX
- Primitives Windows
Comme leur nom l’indique, les primitives Windows ne sont disponibles que sur le système d’exploitation Windows, où elles constituent le backend par défaut. Les deux autres sont généralement toutes deux disponibles sur les systèmes d’exploitation Unix. Le tableau suivant donne un aperçu de leur disponibilité type depuis Qt 6.6 :
| Système d'exploitation | POSIX | System V | Windows |
|---|---|---|---|
| Android | |||
| INTEGRITY | |||
| QNX | Oui | ||
| macOS | Oui | En général (1) | |
| Autres systèmes d'exploitation Apple | Oui | ||
| Autres systèmes Unix | Oui | Oui | |
| Windows | Rarement (2) | Oui |
Remarque : 1 Les applications macOS en mode sandbox, qui incluent toutes les applications distribuées via l'App Store d'Apple, ne peuvent pas utiliser d'objets System V.
Remarque : 2 Certains environnements d'exécution C compatibles GCC sous Windows prennent en charge la mémoire partagée conforme à POSIX, mais cela est rare. Cette fonctionnalité est toujours absente avec le compilateur Microsoft.
Pour déterminer si un type de clé donné est pris en charge, les applications doivent appeler QSharedMemory::isKeyTypeSupported() et QSystemSemaphore::isKeyTypeSupported().
QNativeIpcKey fournit également une prise en charge de la compatibilité avec les applications Qt antérieures à son introduction. Les sections suivantes détaillent les limitations des backends, le contenu des clés de type chaîne de caractères elles-mêmes, ainsi que la compatibilité.
Format de clé multiplateforme sécurisé
QNativeIpcKey::setNativeKey() et QNativeIpcKey::nativeKey() gèrent la clé native de bas niveau, qui peut être utilisée avec les API natives et partagée avec d’autres processus non-Qt (voir ci-dessous pour l’API). Ce format n’étant généralement pas multiplateforme, QSharedMemory et QSystemSemaphore fournissent tous deux une fonction permettant de convertir une chaîne d’identifiant multiplateforme en clé native : QSharedMemory::platformSafeKey() et QSystemSemaphore::platformSafeKey().
Sur la plupart des plateformes, la longueur de la clé multiplateforme est identique à celle d’un nom de fichier, mais elle est strictement limitée à 30 octets utilisables sur les plateformes Apple (veillez à respecter l’encodage UTF-8 si vous utilisez des caractères hors de la plage US-ASCII). Le format de la clé est également similaire à celui d’un composant de chemin d’accès à un fichier, ce qui signifie qu’elle ne doit contenir aucun caractère interdit dans les noms de fichiers, en particulier ceux qui séparent les composants du chemin (barre oblique et barre oblique inversée), à l’exception des applications en mode sandbox sur les systèmes d’exploitation Apple. Voici quelques bons exemples de clés multiplateformes : « myapp », « org.example.myapp », « org.example.myapp-12345 ». Notez qu’il incombe à l’appelant d’éviter les clés trop longues et de s’assurer que la clé contient des caractères autorisés sur la plateforme concernée. Qt tronquera silencieusement les clés trop longues.
Limites du mode « sandbox » d’Apple : si l’application s’exécute dans un environnement « sandbox » sur un système d’exploitation Apple, la clé doit respecter un format très spécifique : <application group identifier>/<custom identifier>. Le mode « sandbox » est implicite pour toutes les applications distribuées via l’App Store d’Apple. Consultez la documentation d’Apple ici et ici pour plus d’informations, notamment sur la manière d’obtenir l’identifiant de groupe de l’application.
Format natif des clés
Cette section détaille le format des clés natives des backends pris en charge.
POSIX en temps réel
Les clés natives ressemblent à des noms de fichiers et peuvent contenir tous les caractères autorisés dans les noms de fichiers, à l’exception de la barre oblique. La norme POSIX exige que le premier caractère du nom de la clé soit une barre oblique et ne précise pas si d’autres barres obliques sont autorisées. Sur la plupart des systèmes d’exploitation, la longueur de la clé est identique à celle d’un nom de fichier, mais elle est limitée à 32 caractères sur les systèmes d’exploitation Apple (ce nombre inclut la première barre oblique et le caractère nul de fin, ce qui ne laisse que 30 caractères utilisables).
Voici quelques bons exemples de clés POSIX natives : « /myapp », « /org.example.myapp », « /org.example.myapp-12345 ».
Les fonctions QSharedMemory::platformSafeKey() et QSystemSemaphore::platformSafeKey() se contentent d'ajouter la barre oblique au début. Sur les systèmes d'exploitation Apple, elles tronquent également le résultat à la taille disponible.
Windows
Les clés Windows sont des noms d’objets du noyau NT et peuvent comporter jusqu’à MAX_PATH (260) caractères. Elles ressemblent à des chemins relatifs (c’est-à-dire qu’elles ne commencent pas par une barre oblique inversée ni par une lettre de lecteur), mais contrairement aux noms de fichiers sous Windows, elles sont sensibles à la casse.
Voici quelques bons exemples de clés Windows natives : « myapp », « org.example.myapp », « org.example.myapp-12345 ».
Les fonctions QSharedMemory::platformSafeKey() et QSystemSemaphore::platformSafeKey() insèrent un préfixe permettant de distinguer respectivement la mémoire partagée et les sémaphores système.
Interfaces système X/Open (XSI) / System V
Les clés System V prennent la forme du nom d’un fichier dans le système et sont donc soumises exactement aux mêmes contraintes que les chemins d’accès aux fichiers. Les fonctions QSharedMemory et QSystemSemaphore créeront ce fichier s’il n’existe pas au moment de la création de l’objet. Si la suppression automatique est désactivée, ce fichier peut également être partagé entre QSharedMemory et QSystemSemaphore sans conflit et peut être n’importe quel fichier existant (par exemple, il peut s’agir de l’exécutable du processus lui-même, voir QCoreApplication::applicationFilePath()). Le chemin doit être absolu afin d’éviter toute erreur due à des répertoires courants différents.
QSharedMemory::platformSafeKey() et QSystemSemaphore::platformSafeKey() renvoient toujours un chemin absolu. Si l’entrée était déjà absolue, elles renvoient l’entrée telle quelle. Sinon, elles y ajoutent en préfixe un chemin approprié dans lequel l’application dispose généralement des droits nécessaires pour créer des fichiers.
Propriété
Les objets de mémoire partagée et de sémaphore système doivent être créés avant utilisation, ce qui s’effectue respectivement à l’aide de ` QSharedMemory::create()` ou en passant ` QSystemSemaphore::Create ` au constructeur.
Sur les systèmes Unix, les classes Qt ayant créé l’objet sont chargées de le nettoyer. Par conséquent, si l’application utilisant cet objet C++ se termine de manière anormale (plantage, appel à ` qFatal()`, etc.), l’objet risque de rester en mémoire. Dans ce cas, les applications risquent de ne pas pouvoir recréer l’objet et devraient plutôt se lier à un objet existant. Par exemple, pour ` QSharedMemory` :
if (!shm.create(4096) && shm.error() == QSharedMemory::AlreadyExists)
shm.attach();Se reconnecter à un ` QSystemSemaphore ` n’est probablement pas judicieux, car le compteur de jetons qu’il contient se trouve sans doute dans un état inconnu et peut donc entraîner des blocages.
POSIX Realtime
La propriété des objets POSIX Realtime s’inspire de celle des fichiers, en ce sens qu’ils existent indépendamment de tout processus, qu’il les utilise ou non. Qt est incapable de déterminer si l’objet est toujours en cours d’utilisation ; par conséquent, la suppression automatique l’éliminera même dans ce cas, ce qui rendra impossible toute nouvelle association à ce même objet, sans toutefois affecter les associations existantes.
Avant Qt 6.6, Qt ne nettoyait jamais les objets POSIX Realtime, sauf sur QNX.
Interfaces système X/Open (XSI) / System V
Deux ressources sont gérées par les classes Qt : le fichier auquel la clé fait référence et l’objet lui-même. ` QSharedMemory ` gère l’objet de manière coopérative : le dernier attachement est chargé de supprimer l’objet lui-même, puis de supprimer le fichier de clé. ` QSystemSemaphore ` supprimera l’objet si et seulement s’il a reçu l’argument ` QSystemSemaphore::Create` ; de plus, s’il a créé le fichier de clé, il le supprimera également.
Depuis Qt 6.6, il est possible de demander à l’une ou l’autre de ces classes de ne pas effectuer le nettoyage.
Windows
Le système d’exploitation est propriétaire de l’objet et se chargera de sa libération une fois que le dernier descripteur pointant vers l’objet aura été fermé.
Interopérabilité avec les anciennes applications Qt
La classe ` QNativeIpcKey ` a été introduite dans Qt 6.6. Avant cette version, les backends ` QSharedMemory ` et ` QSystemSemaphore ` étaient déterminés au moment de la compilation de Qt. Pour les systèmes Windows, il s'agissait toujours du backend Windows. Pour les systèmes Unix, le backend par défaut était System V si le script de configuration déterminait qu’il était disponible. S’il n’était pas disponible, le système se rabattait sur le backend POSIX. Le backend POSIX pouvait être sélectionné explicitement à l’aide de l’option -feature-ipc_posix du script de configuration de Qt ; s’il était activé, la macro QT_POSIX_IPC était définie.
Qt 6.6 conserve l’option du script de configuration, mais celle-ci ne contrôle plus la disponibilité des backends. En revanche, elle modifie la valeur renvoyée par la fonction QNativeIpcKey::legacyDefaultTypeForOs(). Les applications qui doivent préserver la compatibilité doivent utiliser exclusivement ce type de clé pour garantir l’interopérabilité.
L’API, tant dans ` QSharedMemory ` que dans ` QSystemSemaphore `, reposait sur le concept de clé multiplateforme, désormais obsolète au profit de l’utilisation de `QSharedMemory::legacyNativeKey()` et `QSystemSemaphore::legacyNativeKey()`. Ces deux fonctions génèrent la même clé native que les fonctions obsolètes des versions précédentes. Si l'ancien code était par exemple :
QSharedMemory shm("org.example.myapplication");
QSystemSemaphore sem("org.example.myapplication");Il peut être mis à jour comme suit :
QSharedMemory shm(QSharedMemory::legacyNativeKey("org.example.myapplication"));
QSystemSemaphore sem(QSystemSemaphore::legacyNativeKey("org.example.myapplication"));Si les deux applications échangeaient des clés natives, il n’est pas nécessaire de mettre à jour du code tel que :
QSharedMemory shm;
shm.setNativeKey(key);Toutefois, si l’ancienne application acceptait une clé native, la nouvelle peut choisir d’utiliser ` platformSafeKey() ` avec un deuxième argument de type ` QNativeIpcKey::legacyDefaultTypeForOs()`.
Interfaces système X/Open (XSI) / System V
N’utilisez jamais de fichiers existants pour les clés d’ QSharedMemory, car l’ancienne application Qt pourrait tenter de les supprimer. Laissez plutôt QSharedMemory les créer.
Interopérabilité avec les applications non-Qt
L'interopérabilité avec des applications non-Qt est possible, avec certaines limitations :
- La création de segments de mémoire partagée ne doit pas donner lieu à une situation de concurrence
- QSharedMemory la prise en charge du verrouillage du segment n’est pas disponible
La communication avec des applications non-Qt doit toujours s'effectuer via la clé native.
QSharedMemory Le segment est toujours mappé dans son intégralité en mémoire. L'application non-Qt peut choisir de ne mapper qu'une partie de celui-ci en mémoire, sans conséquence négative.
Temps réel POSIX
La mémoire partagée POSIX peut être ouverte à l’aide de `shm_open()` et les sémaphores système POSIX peuvent être ouverts à l’aide de `sem_open()`.
Ces deux fonctions prennent un paramètre « name » qui est le résultat de ` QNativeIpcKey::nativeKey()` (), encodé pour les noms de fichiers à l’aide de ` QFile::encodeName()` / ` QFile::decodeName()`.
Windows
Les objets de mémoire partagée Windows peuvent être ouverts à l’aide de CreateFileMappingW et les objets de sémaphore système Windows à l’aide de CreateSemaphoreW. Bien que le nom de ces deux fonctions commence par « Create », elles permettent de s’associer à des objets existants.
Le paramètre « lpName » de ces fonctions correspond au résultat de la fonction QNativeIpcKey::nativeKey(), sans transformation.
Si l’application externe utilise la version non-Unicode de ces fonctions (se terminant par « A »), le nom peut être converti en 8 bits et inversement à l’aide de QString.
Interfaces système X/Open (XSI) / System V
La mémoire partagée System V peut être obtenue à l’aide de shmget() et les sémaphores système System V peuvent être obtenus à l’aide de semget().
Le paramètre ` key ` de l’une ou l’autre de ces fonctions correspond au résultat de la fonction `ftok()` lorsqu’on lui transmet le nom de fichier obtenu via ` QNativeIpcKey::nativeKey()` avec un ` id ` de 81 ou 0x51 (la lettre majuscule ASCII « Q »).
Les objets sémaphores System V peuvent contenir plusieurs sémaphores, mais QSystemSemaphore n’utilise que le premier (numéro 0 pour sem_num).
QSharedMemory et QSystemSemaphore suppriment par défaut l’objet à l’aide de l’opération « IPC_RMID » vers shmctl() et semctl() respectivement s’ils constituent le dernier attachement.
© 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.