Auf dieser Seite

Native IPC-Schlüssel

Die Klassen „ QSharedMemory “ und „ QSystemSemaphore “ identifizieren ihre Ressource mithilfe eines systemweiten Bezeichners, der als „Schlüssel“ bezeichnet wird. Der Low-Level-Schlüsselwert sowie der Schlüsseltyp werden in Qt mithilfe der Klasse „ QNativeIpcKey “ gekapselt. Diese Klasse bietet zudem die entsprechenden Mittel zum Austausch des Schlüssels mit anderen Prozessen über die Methoden „ QNativeIpcKey::toString()“ und „ QNativeIpcKey::fromString()“.

Qt unterstützt derzeit drei verschiedene Backends für diese beiden Klassen, die den in der Aufzählung ` QNativeIpcKey::Type ` verfügbaren Werten entsprechen.

  • POSIX-Echtzeit-Erweiterungen (IEEE 1003.1b, POSIX.1b)
  • X/Open-Systemschnittstellen (XSI) oder System V (SVr4), die mittlerweile jedoch ebenfalls Teil von POSIX sind
  • Windows-Primitive

Wie der Name schon sagt, sind die Windows-Primitive nur unter dem Windows-Betriebssystem verfügbar, wo sie das Standard-Backend darstellen. Die beiden anderen sind in der Regel beide auf Unix-Betriebssystemen verfügbar. Die folgende Tabelle bietet einen Überblick über die typische Verfügbarkeit seit Qt 6.6:

BetriebssystemPOSIXSystem VWindows
Android
INTEGRITY
QNXJa
macOSJaIn der Regel (1)
Andere Apple-BetriebssystemeJa
Andere Unix-SystemeJaJa
WindowsSelten (2)Ja

Hinweis: 1 MacOS-Anwendungen in einer Sandbox, zu denen alle über den Apple App Store vertriebenen Anwendungen gehören, dürfen keine System-V-Objekte verwenden.

Hinweis: 2 Einige GCC-kompatible C-Laufzeitumgebungen unter Windows bieten Unterstützung für POSIX-kompatiblen Shared Memory, dies ist jedoch selten der Fall. Beim Microsoft-Compiler fehlt diese Unterstützung grundsätzlich.

Um festzustellen, ob ein bestimmter Schlüsseltyp unterstützt wird, sollten Anwendungen die Funktionen `QSharedMemory::isKeyTypeSupported()` und `QSystemSemaphore::isKeyTypeSupported()` aufrufen.

QNativeIpcKey bietet zudem Unterstützung für die Kompatibilität mit Qt-Anwendungen, die vor der Einführung dieser Funktion erstellt wurden. In den folgenden Abschnitten werden die Einschränkungen der Backends, der Inhalt der String-Schlüssel selbst sowie die Kompatibilität näher erläutert.

Plattformübergreifendes sicheres Schlüsselformat

QNativeIpcKey::setNativeKey() und ` QNativeIpcKey::nativeKey()` verarbeiten den nativen Schlüssel auf niedriger Ebene, der mit den nativen APIs verwendet und mit anderen, nicht zu Qt gehörenden Prozessen gemeinsam genutzt werden kann (siehe unten für die API). Dieses Format ist in der Regel nicht plattformübergreifend, daher stellen sowohl ` QSharedMemory ` als auch ` QSystemSemaphore ` eine Funktion zur Verfügung, um eine plattformübergreifende Kennungszeichenfolge in den nativen Schlüssel zu übersetzen: `QSharedMemory::platformSafeKey()` und `QSystemSemaphore::platformSafeKey()`.

Die Länge des plattformübergreifenden Schlüssels entspricht auf den meisten Plattformen der eines Dateinamens, ist jedoch auf Apple-Plattformen stark auf nur 30 nutzbare Bytes begrenzt (beachten Sie die UTF-8-Kodierung, wenn Sie Zeichen außerhalb des US-ASCII-Bereichs verwenden). Das Format des Schlüssels ähnelt zudem dem einer Dateipfadkomponente, was bedeutet, dass er keine Zeichen enthalten darf, die in Dateinamen unzulässig sind, insbesondere solche, die Pfadkomponenten trennen (Schrägstrich und Backslash), mit Ausnahme von Sandbox-Anwendungen auf Apple-Betriebssystemen. Folgende Beispiele sind gute Beispiele für plattformübergreifende Schlüssel: „myapp“, „org.example.myapp“, „org.example.myapp-12345“. Beachten Sie, dass es Aufgabe des Aufrufers ist, überlange Schlüssel zu vermeiden und sicherzustellen, dass der Schlüssel auf der jeweiligen Plattform zulässige Zeichen enthält. Qt kürzt zu lange Schlüssel stillschweigend.

Einschränkungen durch die Apple-Sandbox: Wenn die Anwendung in einer Sandbox auf einem Apple-Betriebssystem ausgeführt wird, muss der Schlüssel ein ganz bestimmtes Format haben: <application group identifier>/<custom identifier>. Für alle Anwendungen, die über den Apple App Store vertrieben werden, gilt implizit die Sandbox-Einschränkung. Weitere Informationen, darunter auch, wie man die Gruppen-ID der Anwendung ermittelt, finden Sie in der Dokumentation von Apple hier und hier.

Natives Schlüsselformat

In diesem Abschnitt wird das Format der nativen Schlüssel der unterstützten Backends beschrieben.

POSIX Realtime

Native Schlüssel ähneln Dateinamen und dürfen alle Zeichen enthalten, die auch in Dateinamen zulässig sind, mit Ausnahme eines Schrägstrichs. POSIX schreibt vor, dass das erste Zeichen im Schlüsselnamen ein Schrägstrich sein muss, lässt jedoch offen, ob weitere Schrägstriche zulässig sind. Auf den meisten Betriebssystemen entspricht die Schlüssellänge der eines Dateinamens, ist jedoch auf Apple-Betriebssystemen auf 32 Zeichen begrenzt (dazu gehören der erste Schrägstrich und das abschließende Nullzeichen, sodass nur 30 nutzbare Zeichen möglich sind).

Die folgenden Beispiele sind gute Beispiele für native POSIX-Schlüssel: „/myapp“, „/org.example.myapp“, „/org.example.myapp-12345“.

QSharedMemory::platformSafeKey() und QSystemSemaphore::platformSafeKey() fügen einfach den Schrägstrich am Anfang hinzu. Auf Apple-Betriebssystemen kürzen sie das Ergebnis zudem auf die verfügbare Größe.

Windows

Schlüsseltypen unter Windows sind NT-Kernel-Objektnamen und dürfen bis zu MAX_PATH (260) Zeichen lang sein. Sie sehen aus wie relative Pfade (das heißt, sie beginnen nicht mit einem Backslash oder einem Laufwerksbuchstaben), aber im Gegensatz zu Dateinamen unter Windows wird bei ihnen die Groß-/Kleinschreibung beachtet.

Die folgenden Beispiele sind gute Beispiele für native Windows-Schlüssel: „myapp“, „org.example.myapp“, „org.example.myapp-12345“.

QSharedMemory::platformSafeKey() und QSystemSemaphore::platformSafeKey() fügen jeweils ein Präfix ein, um Shared Memory bzw. System-Semaphoren eindeutig zu kennzeichnen.

X/Open System Interfaces (XSI) / System V

System-V-Schlüssel haben die Form eines Dateinamens im System und unterliegen daher genau denselben Einschränkungen wie Dateipfade. Sowohl ` QSharedMemory ` als auch ` QSystemSemaphore ` erstellen diese Datei, falls sie beim Erstellen des Objekts noch nicht existiert. Wenn die automatische Entfernung deaktiviert ist, kann sie auch konfliktfrei zwischen QSharedMemory und QSystemSemaphore gemeinsam genutzt werden und kann eine beliebige vorhandene Datei sein (zum Beispiel kann es sich um die ausführbare Datei des Prozesses selbst handeln, siehe QCoreApplication::applicationFilePath()). Der Pfad sollte absolut sein, um Fehler aufgrund unterschiedlicher aktueller Verzeichnisse zu vermeiden.

QSharedMemory::platformSafeKey() und QSystemSemaphore::platformSafeKey() geben immer einen absoluten Pfad zurück. War die Eingabe bereits absolut, geben sie diese unverändert zurück. Andernfalls fügen sie einen geeigneten Pfad vor, in dem die Anwendung üblicherweise die Berechtigung zum Erstellen von Dateien hat.

Eigentumsrechte

Shared-Memory- und System-Semaphor-Objekte müssen vor der Verwendung erstellt werden, was jeweils mit ` QSharedMemory::create()` oder durch die Übergabe von ` QSystemSemaphore::Create ` an den Konstruktor erfolgt.

Auf Unix-Systemen sind die Qt-Klassen, die das Objekt erstellt haben, für die Bereinigung des betreffenden Objekts verantwortlich. Wenn die Anwendung mit diesem C++-Objekt daher nicht ordnungsgemäß beendet wird (Absturz, ` qFatal()` usw.), kann das Objekt zurückbleiben. In diesem Fall können Anwendungen möglicherweise das Objekt nicht erneut erstellen und sollten sich stattdessen an ein bestehendes Objekt anhängen. Beispielsweise für ` QSharedMemory`:

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

Das erneute Anbinden an ein ` QSystemSemaphore ` ist wahrscheinlich unklug, da sich der darin enthaltene Token-Zähler vermutlich in einem unbekannten Zustand befindet und dies daher zu Deadlocks führen kann.

POSIX-Echtzeit

Die Eigentumsverhältnisse bei POSIX-Echtzeit-Objekten sind an Dateien angelehnt, insofern, als sie unabhängig davon existieren, ob ein Prozess sie gerade nutzt oder nicht. Qt kann nicht feststellen, ob das Objekt noch in Gebrauch ist; daher wird es durch die automatische Bereinigung auch in diesem Fall entfernt, was eine erneute Anbindung an dasselbe Objekt unmöglich macht, bestehende Anbindungen jedoch nicht beeinträchtigt.

Vor Qt 6.6 hat Qt POSIX-Realtime-Objekte nie bereinigt, außer unter QNX.

X/Open-Systemschnittstellen (XSI) / System V

Es gibt zwei Ressourcen, die von den Qt-Klassen verwaltet werden: die Datei, auf die sich der Schlüssel bezieht, und das Objekt selbst. „ QSharedMemory “ verwaltet das Objekt kooperativ: Die letzte Verknüpfung ist dafür verantwortlich, das Objekt selbst zu entfernen und anschließend die Schlüsseldatei zu löschen. „ QSystemSemaphore “ entfernt das Objekt genau dann, wenn es an „ QSystemSemaphore::Create “ übergeben wurde; zusätzlich entfernt es die Schlüsseldatei, sofern es diese erstellt hat.

Seit Qt 6.6 ist es möglich, beide Klassen anzuweisen, keine Bereinigung durchzuführen.

Windows

Das Betriebssystem ist Eigentümer des Objekts und übernimmt die Bereinigung, sobald der letzte Handle auf das Objekt geschlossen wird.

Interoperabilität mit alten Qt-Anwendungen

Die Klasse „ QNativeIpcKey “ wurde in Qt 6.6 eingeführt. Vor dieser Version wurden die Backends „ QSharedMemory “ und „ QSystemSemaphore “ zum Zeitpunkt des Qt-eigenen Builds festgelegt. Bei Windows-Systemen war dies stets das Windows-Backend. Bei Unix-Systemen wurde standardmäßig das System-V-Backend verwendet, sofern das Konfigurationsskript dessen Verfügbarkeit feststellte. War es nicht verfügbar, wurde auf das POSIX-Backend zurückgegriffen. Das POSIX-Backend konnte explizit über die Option „ -feature-ipc_posix “ des Qt-Konfigurationsskripts ausgewählt werden; war diese aktiviert, wurde das Makro „ QT_POSIX_IPC “ definiert.

Qt 6.6 behält die Option im Konfigurationsskript bei, sie steuert jedoch nicht mehr die Verfügbarkeit der Backends. Stattdessen ändert sie den Rückgabewert von ` QNativeIpcKey::legacyDefaultTypeForOs()`. Anwendungen, die die Kompatibilität wahren müssen, müssen ausschließlich diesen Schlüsseltyp verwenden, um die Interoperabilität zu gewährleisten.

Die API sowohl in ` QSharedMemory ` als auch in ` QSystemSemaphore ` basierte auf dem Konzept eines plattformübergreifenden Schlüssels, der nun zugunsten der Verwendung von `QSharedMemory::legacyNativeKey()` und `QSystemSemaphore::legacyNativeKey()` veraltet ist. Diese beiden Funktionen erzeugen denselben nativen Schlüssel wie die veralteten Funktionen in früheren Versionen. Wenn der alte Code beispielsweise so aussah:

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

kann er wie folgt aktualisiert werden:

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

Wenn die beiden Anwendungen native Schlüssel ausgetauscht haben, muss Code wie der folgende nicht aktualisiert werden:

QSharedMemory shm;
shm.setNativeKey(key);

Wenn die ältere Anwendung jedoch einen nativen Schlüssel akzeptiert hat, kann die neue Anwendung „ platformSafeKey() “ mit dem zweiten Argument „ QNativeIpcKey::legacyDefaultTypeForOs()“ verwenden.

X/Open-Systemschnittstellen (XSI) / System V

Verwenden Sie niemals vorhandene Dateien für ` QSharedMemory `-Schlüssel, da die alte Qt-Anwendung versuchen könnte, diese zu entfernen. Lassen Sie stattdessen ` QSharedMemory ` die Datei erstellen.

Interoperabilität mit Nicht-Qt-Anwendungen

Die Interoperabilität mit Nicht-Qt-Anwendungen ist mit einigen Einschränkungen möglich:

  • Die Erstellung von Shared-Memory-Segmenten darf nicht zu einem Wettlauf führen
  • QSharedMemory Es gibt keine Unterstützung für die Sperrung des Segments

Die Kommunikation mit Nicht-Qt-Anwendungen muss immer über den nativen Schlüssel erfolgen.

QSharedMemory Das gesamte Segment wird immer in den Speicher abgebildet. Die Nicht-Qt-Anwendung kann wählen, nur einen Teil davon in den Speicher abzubilden, ohne dass dies negative Auswirkungen hat.

POSIX-Echtzeit

POSIX-Shared-Memory kann mit shm_open() und POSIX-System-Semaphoren mit sem_open() geöffnet werden.

Beide Funktionen nehmen einen Parameter vom Typ „ name “ entgegen, der das Ergebnis von ` QNativeIpcKey::nativeKey()` ist, wobei Dateinamen mit ` QFile::encodeName()` bzw. ` QFile::decodeName()` kodiert werden.

Windows

Gemeinsam genutzte Speicherobjekte unter Windows können mit `CreateFileMappingW` geöffnet werden, und Windows-System-Semaphorobjekte können mit `CreateSemaphoreW` geöffnet werden. Obwohl die Namen beider Funktionen mit „Create“ beginnen, können sie an bestehende Objekte angehängt werden.

Der Parameter „ lpName “ dieser Funktionen ist das Ergebnis von „ QNativeIpcKey::nativeKey()“, ohne Umwandlung.

Verwendet die fremde Anwendung die Nicht-Unicode-Version dieser Funktionen (die auf „A“ endet), kann der Name mithilfe von ` QString` in 8-Bit konvertiert und wieder zurückkonvertiert werden.

X/Open-Systemschnittstellen (XSI) / System V

System-V-Shared-Memory kann mit shmget() und System-V-System-Semaphoren mit semget() abgerufen werden.

Der Parameter ` key ` für jede dieser Funktionen ist das Ergebnis der Funktion `ftok()`, wenn ihr der von ` QNativeIpcKey::nativeKey()` erhaltene Dateiname mit dem ` id ` 81 oder 0x51 (dem ASCII-Großbuchstaben „Q“) übergeben wird.

System-V-Semaphor-Objekte können mehrere Semaphoren enthalten, aber QSystemSemaphore verwendet nur den ersten (Nummer 0 bei sem_num).

Sowohl QSharedMemory als auch QSystemSemaphore entfernen das Objekt standardmäßig mithilfe der Operation „ IPC_RMID “ zu shmctl() bzw. semctl(), sofern sie die letzte Anbindung sind.

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