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. Beim Google-Herumdenken fand ich, dass vxWorks und die Interprozess-Header der Boost-Bibliotheken ( 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?
Antworten:
Der Boost-Interprozess-Mechanismus besteht aus drei erforderlichen Komponenten:
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.
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.).
Synchronisationsmechanismus; Dies kann ein beliebiger Interprozess-Mutex sein und sollte verwendet werden, um Datenzugriffsbedingungen zu verhindern.
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.
quelle
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).
quelle
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.
quelle
std::atomic
Vorlagenklasse ( cplusplus.com/reference/atomic ) in jedem der beiden Programme verwenden müssen, damit sie in den gemeinsam genutzten Bereich schreiben können ohne Synchronisation über Sperren erzwungen?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:
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
Einige Synchronisationsprimitive benötigen möglicherweise spezielle Flags oder Attribute, um zwischen Prozessen ordnungsgemäß zu funktionieren (siehe beispielsweise das
PTHREAD_PROCESS_SHARED
Attribut für POSIX-Thread-Mutexe). 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:
Auf die gleiche Weise kommunizieren verschiedene Threads, wobei die oben genannten Einschränkungen berücksichtigt werden
Ja, die Kommunikation von Prozessen über den gemeinsam genutzten Speicher ist genauso unsicher wie die Kommunikation von Threads über den gemeinsam genutzten Speicher. Sie benötigen eine gleichwertige (oder identische) Synchronisierung, um die Sicherheit zu gewährleisten.
quelle
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 in C ++ 14 (dessen Entwurf n3690 und vermutlich offizieller Standard Shared Memory außerhalb von Multithreading nicht erwähnt) nicht möglich ). 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 POCO- Framework-Bibliothek 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 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 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 eine Thread-Bibliothek definiert .
quelle