it-swarm.com.de

So teilen Sie Speicher zwischen in C / C ++ geschriebenen Anwendungen

Ich gehe durch ein in C/C++ geschriebenes Programm zur Steuerung in der Robotik. Grundsätzlich werden drei verschiedene Programme gleichzeitig ausgeführt und kommunizieren über den gemeinsamen Speicher. Google-ling herum fand ich denkt wie vxWorks und die Boost-Bibliotheken Interprozess-Header ( Boost-Dokumentation: Speicher zwischen Prozessen teilen ).

Jetzt möchte ich nicht auf die Implementierung schauen, ich kann den obigen Link lesen. Aber ich kann mir nicht vorstellen, wie die Boost-Bibliothek das macht. Ich meine, eine Anwendung weist Speicher zu und andere greifen auf diesen Speicher zu, aber wie kommunizieren sie? Ist es nicht unsicher, dies zu tun?

9
cauchy

Aber ich kann mir nicht vorstellen, wie die Boost-Bibliothek das macht.

Der Boost-Interprozess-Mechanismus besteht aus drei erforderlichen Komponenten:

  1. speicherzuordnungsdatei: Eine Speicherzuordnungsdatei muss erstellt und an einen Boost.interprocess-Allokator übergeben werden. Dieser Allokator nimmt Teile der Datei und verwendet sie so, als ob sie von einem std :: allocator zurückgegeben würden, wobei die Zuordnung angewendet wird, damit der Speicher mit dem prozessspezifischen Speicher kompatibel ist.

  2. boost.interprocess container; Diese Art von Container verwendet den vom Allokator zurückgegebenen Speicher und bietet eine std :: container-ähnliche Schnittstelle (begin/end/size/Push_back usw.).

  3. synchronisationsmechanismus; Dies kann ein beliebiger Interprozess-Mutex sein und sollte verwendet werden, um Datenzugriffsbedingungen zu verhindern.

Ich meine, eine Anwendung weist Speicher zu und andere greifen auf diesen Speicher zu, aber wie kommunizieren sie? Ist es nicht unsicher, dies zu tun?

Der zugewiesene Speicher ist tatsächlich eine gemeinsam genutzte Speicherzuordnungsdatei. Die Kommunikation erfolgt indirekt, wobei beide Anwendungen die Daten nach Bedarf einstellen oder lesen. Die Sicherheit ergibt sich aus der Verwendung von Interprozess-Synchronisationsprimitiven.

11
utnapistim

shared Memory ist nicht das vollständige Bild für IPC, sondern ein Datenübergabemechanismus. Sie müssen jedoch den anderen Prozess darüber informieren, dass einige Daten aktualisiert wurden und zum Lesen verfügbar sind. Wie Sie dies tun, liegt bei Ihnen. Normalerweise verwenden Sie einen Betriebssystem-Mutex oder ein Ereignisobjekt. Jeder Prozess wartet darauf, dass dies festgelegt wird. Das Schreiben der Anwendung legt es fest, sobald das Schreiben abgeschlossen ist. Dann werden Threads in den anderen Programmen aktiviert und gelesen.

Alternativ können Sie die Daten regelmäßig abfragen, um einen Wert zu finden, der sich ändert, wenn die Daten aktualisiert werden (z. B. einen inkrementierenden Zähler).

5
gbjbaanb

Boost verwendet die Speicherzuordnung einer Datei.

Sowohl Unix als auch Windows unterstützen die Erstellung von Dateien, die im normalen Dateisystem nicht vorhanden sind.

Dann müssen Sie den Zugriff auf diesen Speicher so synchronisieren, wie Sie es tun würden, wenn verschiedene Threads darauf zugreifen würden. Das bedeutet, dass gleichzeitige Lesevorgänge ohne Synchronisierung erfolgen können. Sobald jedoch ein Prozess schreiben möchte, müssen Sie verhindern, dass die anderen darauf zugreifen.

Atomische Operationen im gemeinsam genutzten Speicher sind weiterhin möglich, wenn Sie eine sperrenlose Synchronisation wünschen.

4
ratchet freak

Beachten Sie, dass C und C++ unterschiedliche Sprachen sind.

Shared Memory ist in reinem Standard C11 oder C++ 11 (da der Standard dies nicht definiert) oder sogar C +) unmöglich +14 (dessen n369 Entwurf und vermutlich offizieller Standard Shared Memory außerhalb von Multithreading nicht erwähnt). Sie benötigen also zusätzliche Bibliotheken, um gemeinsam genutzten Speicher zu erhalten. Einige Betriebssysteme unterstützen jedoch gemeinsam genutzten Speicher. Es gibt also mehrere Bibliotheken, die gemeinsam genutzten Speicher bereitstellen und auf vorhandenen Betriebssystemdiensten aufbauen. Sie könnten vielleicht in Betracht ziehen, die Framework-Bibliothek POCO zu verwenden (die über betriebssystemspezifische Details abstrahiert).

Schauen Sie sich für Linux (und möglicherweise POSIX) shm_overview (7) an. Sie müssen synchronisieren, siehe auch sem_overview (7)

VXWorks (das ich nicht kenne, aber dafür gegoogelt habe) hat VxMP

Sie müssen sorgfältig verstehen, was wirklich passiert. Sie möchten wahrscheinlich nur einfache alte Daten struct- s (keine C++ - Klassen!) Freigeben, und Sie sollten sehr vorsichtig mit den Adressen (jeder Prozess erhält möglicherweise eine andere Adresse für das gemeinsame gemeinsam genutzte Speichersegment) und der Synchronisation sein.

Alternativ können Sie Threads verwenden. Beachten Sie, dass der C++ 11-Standard ein Thread-Bibliothek definiert.

Shared Memory ist immer noch nur Speicher. Sie können dort einen Mutex, einen Spinlock oder ein anderes Synchronisationsprimitiv einfügen und damit den Zugriff Ihrer Prozesse auf den gemeinsam genutzten Speicher synchronisieren, genau wie Threads diese Primitive verwenden, um den Zugriff auf den für sie sichtbaren Speicher zu synchronisieren.

Die einzigen wirklichen Unterschiede sind:

  1. threads teilen sich den gesamten Speicher und den gleichen Adressraum, sodass rohe Zeiger für sie funktionieren. Der von den Prozessen gemeinsam genutzte Speicher funktioniert genauso, kann jedoch in jedem Prozess an verschiedenen Adressen zugeordnet werden, sodass Sie nicht einfach Rohzeiger zwischen ihnen übergeben können

    • NB. Dies wirkt sich auf einige Implementierungsdetails virtueller Methoden, Laufzeittypinformationen und einige andere C++ - Mechanismen aus. Halten Sie sich an trivial initialisierbare Typen (einfache alte Daten) ohne virtuelle Methoden oder dynamische Umwandlungen in Ihrem gemeinsam genutzten Speicher, verwenden Sie keine Typ-ID für sie, und es sollte Ihnen gut gehen.
  2. einige Synchronisationsprimitive benötigen möglicherweise spezielle Flags oder Attribute, um zwischen Prozessen korrekt zu funktionieren (siehe PTHREAD_PROCESS_SHARED Attribut für POSIX-Thread-Mutexe, zum Beispiel). Dies hat nicht wirklich mit dem Speicher und der Synchronisation an sich zu tun, sondern mit der Kernel/Scheduler-Interaktion, die erforderlich ist, um schlafende Kellner aufzuwecken.


Damit:

aber wie kommunizieren sie?

Auf die gleiche Weise kommunizieren verschiedene Threads, wobei die oben genannten Einschränkungen berücksichtigt werden

ist es nicht unsicher, dies zu tun?

Ja, die Kommunikation von Prozessen über den gemeinsam genutzten Speicher ist genauso unsicher wie die Kommunikation von Threads über den gemeinsam genutzten Speicher, und sie benötigen eine gleichwertige (oder identische) Synchronisierung mit make it safe.

3
Useless