Mémoire partagée
Qt propose deux techniques pour partager de la mémoire avec d’autres processus au sein d’un même système : les segments de mémoire partagée ( QSharedMemory ) et les fichiers mappés en mémoire ( QFile). La mémoire partagée avec d’autres processus est souvent appelée « segment » ; bien qu’elle ait pu être implémentée sous forme de segments spécifiques sur des processeurs dotés de modèles de mémoire segmentée par le passé, ce n’est plus le cas dans aucun système d’exploitation moderne. Les segments de mémoire partagée sont simplement des zones de mémoire dont le système d’exploitation garantit la disponibilité pour tous les processus participants.
Remarque : l’adresse à laquelle le segment est situé en mémoire sera presque toujours différente pour chaque processus participant au partage. Par conséquent, les applications doivent veiller à ne partager que des données indépendantes de la position, telles que les types primitifs C++ ou les tableaux de ces types.
Partage de mémoire à l’aide de QSharedMemory
QSharedMemory fournit une API simple pour créer un segment de mémoire partagée d’une taille donnée ou pour s’attacher à un segment créé par un autre processus. De plus, elle propose deux méthodes permettant de « lock » et « unlock » l’ensemble du segment, à l’aide d’un « QSystemSemaphore » interne.
Les segments de mémoire partagée et les sémaphores système sont identifiés globalement dans le système par une « clé », qui, dans Qt, est représentée par la classe ` QNativeIpcKey `. De plus, selon le système d’exploitation, Qt peut prendre en charge plusieurs backends différents pour le partage de mémoire ; consultez la documentation sur les clés IPC natives pour plus d’informations et pour connaître les limitations.
QSharedMemory est conçu pour partager la mémoire uniquement au sein d’un même niveau de privilège (c’est-à-dire pas avec d’autres processus non fiables, tels que ceux lancés par d’autres utilisateurs). Pour les backends qui le prennent en charge, QSharedMemory créera des segments de telle sorte que seuls les processus disposant du même niveau de privilège puissent s’y attacher.
Partage de mémoire via des fichiers mappés en mémoire
La plupart des fichiers peuvent être mappés en mémoire à l’aide de ` QFile::map()` et, si l’option ` MapPrivateOption ` n’est pas spécifiée, toute écriture sur le segment mappé sera visible par tous les autres processus ayant mappé le même fichier. Parmi les exceptions aux fichiers pouvant être mappés en mémoire figurent les fichiers distants situés sur des partages réseau ou ceux se trouvant dans certains systèmes de fichiers. Même si le système d’exploitation autorise le mappage de fichiers distants en mémoire, les opérations d’E/S sur le fichier seront probablement mises en cache et retardées, rendant ainsi impossible un véritable partage de mémoire.
Cette solution présente les avantages majeurs d’être indépendante de toute API backend et d’offrir une interopérabilité plus simple avec les applications non-Qt. Étant donné que ` QTemporaryFile ` est une ` QFile`, les applications peuvent utiliser cette classe pour mettre en œuvre une sémantique de nettoyage et créer également des segments de mémoire partagée uniques.
Pour verrouiller le segment de mémoire partagée, les applications devront mettre en œuvre leurs propres mécanismes. Une solution consiste à utiliser ` QLockFile`. Une autre solution, moins coûteuse, consiste à utiliser ` QAtomicInteger ` ou ` std::atomic ` à un décalage prédéterminé dans le segment lui-même. Des primitives de verrouillage de plus haut niveau peuvent être disponibles sur certains systèmes d’exploitation ; par exemple, sous Linux, les applications peuvent définir l’indicateur « pshared » dans l’attribut du mutex transmis à ` pthread_mutex_create() ` pour indiquer que le mutex réside dans un segment de mémoire partagée.
Sachez que le système d’exploitation tentera probablement de valider en mémoire permanente toute écriture effectuée dans la mémoire partagée. Cela peut être souhaitable, mais peut également entraîner une perte de performances si le fichier lui-même était destiné à être temporaire. Dans ce cas, les applications doivent utiliser un système de fichiers adossé à la RAM, tel que tmpfs sous Linux (voir QStorageInfo::fileSystemType()), ou passer un indicateur à la fonction native d’ouverture de fichier pour indiquer au système d’exploitation d’éviter de valider le contenu sur le stockage.
Il est possible d’utiliser de la mémoire partagée basée sur des fichiers pour communiquer avec des processus non fiables ; dans ce cas, l’application doit faire preuve d’une grande prudence. Les fichiers peuvent être tronqués ou réduits, ce qui peut entraîner le plantage des applications accédant à la mémoire au-delà de la taille du fichier.
Conseils Linux sur les fichiers mappés en mémoire
Sur les systèmes Linux modernes, bien que le répertoire /tmp soit souvent un point de montage tmpfs, ce n’est pas une obligation. En revanche, le répertoire /dev/shm doit impérativement être un tmpfs et existe précisément dans le but de partager de la mémoire. Notez qu’il est accessible en lecture et en écriture par tous (à l’instar de /tmp et /var/tmp), les applications doivent donc faire attention aux contenus qui y sont exposés. Une autre alternative consiste à utiliser le répertoire d’exécution XDG (voir QStandardPaths::writableLocation() et QStandardPaths::RuntimeLocation), qui, sur les systèmes Linux utilisant systemd, est un répertoire spécifique à l’utilisateur tmpfs.
Une solution encore plus sécurisée consiste à créer un « memfd » à l’aide de memfd_create(2) et à utiliser la communication interprocessus pour transmettre le descripteur de fichier, par exemple via QDBusUnixFileDescriptor ou en le faisant hériter par le processus fils d’un QProcess. Les « memfds » peuvent également être verrouillés pour empêcher toute réduction de taille, ce qui permet de les utiliser en toute sécurité lors de la communication avec des processus disposant d’un niveau de privilège différent.
Conseils concernant les fichiers mappés en mémoire sous FreeBSD
FreeBSD dispose également de memfd_create(2) et peut transmettre des descripteurs de fichiers à d’autres processus en utilisant les mêmes techniques que Linux. Il ne dispose pas de systèmes de fichiers temporaires montés par défaut.
Conseils pour Windows concernant les fichiers mappés en mémoire
Sous Windows, l’application peut demander au système d’exploitation d’éviter d’enregistrer le contenu du fichier sur un support de stockage permanent. Cette demande s’effectue en passant le drapeau « FILE_ATTRIBUTE_TEMPORARY » dans le paramètre « dwFlagsAndAttributes » de la fonction Win32 « CreateFile », le drapeau « _O_SHORT_LIVED » à la fonction de bas niveau « _open() », ou en incluant le modificateur « T » à la fonction d’exécution C « fopen() ».
Il existe également un indicateur permettant d’indiquer au système d’exploitation de supprimer le fichier lorsque le dernier descripteur y afférent est fermé (FILE_FLAG_DELETE_ON_CLOSE, _O_TEMPORARY et le modificateur « D »), mais notez que tous les processus tentant d’ouvrir le fichier doivent s’accorder sur l’utilisation ou non de cet indicateur. Une divergence entraînera probablement une violation de partage et un échec de l’ouverture du fichier.
© 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.