Wir benötigen mehrere Programme, um Funktionen in einer gemeinsamen Bibliothek aufzurufen. Die Bibliotheksfunktionen greifen auf einen gemeinsamen globalen Speicher zu und aktualisieren ihn. Die Funktionsaufrufe jedes Programms müssen diesen gemeinsamen globalen Speicher sehen. Das heißt, ein Funktionsaufruf muss die Aktualisierungen eines vorherigen Funktionsaufrufs sehen, selbst wenn er von einem anderen Programm aufgerufen wird. Aus Kompatibilitätsgründen haben wir einige Design-Einschränkungen für die Funktionsweise der Funktionen, die von der gemeinsam genutzten Bibliothek bereitgestellt werden:
Eine Lösung besteht darin, den gemeinsamen globalen Speicher der Bibliothek in den benannten gemeinsamen Speicher zu stellen. Der erste Bibliotheksaufruf würde den benannten gemeinsamen Speicher erstellen und initialisieren. Nachfolgende Programmaufrufe würden die Adresse des gemeinsamen Speichers abrufen und sie als Zeiger auf die globale Datenstruktur verwenden. Objektinstanzen, die global deklariert werden, müssen dynamisch im gemeinsam genutzten Speicher zugewiesen werden, während lokal deklarierte Objektinstanzen auf dem Stapel oder im lokalen Heap des aufrufenden Threads platziert werden können. Probleme treten auf, weil initialisierte Objekte im globalen Speicher Unterobjekte erzeugen und anzeigen können, die (neuen) zusätzlichen Speicher zuweisen. Diese neuen Zuweisungen müssen sich auch im gemeinsamen Speicher befinden und von allen Bibliotheksanrufern gesehen werden. Eine weitere Komplikation ist, dass diese Objekte, die Strings, Dateien usw. enthalten, auch im aufrufenden Programm verwendet werden können. Wenn im aufrufenden Programm deklariert, ist der Speicher des Objekts lokal für das aufrufende Programm, nicht freigegeben. Der Code des Objekts muss also mit beiden Fällen umgehen. Es scheint uns, dass die Lösung erfordert, dass wir die globalen Platzierungen für neue, reguläre neue und Löschoperatoren überschreiben. Wir haben einen Entwurf für ein Speicherverwaltungssystem gefunden, der aussieht, als würde er funktionieren, aber wir haben keine tatsächlichen Implementierungen gefunden. Wenn jemand eine Implementierung von Nathan Myers 'Memory Management Design ( Ссылка ) kennt, würde ich mich über einen Link freuen es. Wenn jemand einen anderen Shared-Memory-Manager kennt, der dynamisch allokierende Objekte aufnimmt, würde ich es auch gerne wissen. Ich habe die Boost-Bibliotheken und all die anderen Quellen überprüft, die ich finden kann, aber nichts scheint zu tun, was wir brauchen. Wir bevorzugen es, nicht selbst schreiben zu müssen. Da Leistung und Robustheit wichtig sind, wäre es gut, bewährten Code zu verwenden. Vielen Dank im Voraus für jede Idee / Hilfe.
Danke für die Vorschläge zu den ATL- und OSSP-Bibliotheken. Ich überprüfe sie jetzt, obwohl ich befürchte, dass ATL zu Wincentric ist, wenn sich herausstellt, dass das Ziel Unix ist.
Eine andere Sache scheint uns jetzt klar zu sein. Da Objekte während der Ausführung dynamisch erstellt werden können, muss das Speicherverwaltungsschema in der Lage sein, zusätzliche Seiten mit gemeinsam genutztem Speicher zuzuweisen. Dies fängt jetzt an, wie ein ausgewachsener Heap-Ersatz-Speichermanager auszusehen.
Wie Sie sicher herausgefunden haben, ist dies ein sehr komplexes Problem und sehr schwer korrekt zu implementieren. Ein paar Tipps aus meinen Erfahrungen. Zuallererst wollen Sie den Zugriff auf die Shared-Memory-Zuweisungen mit Semaphoren definitiv synchronisieren. Zweitens müssen alle Änderungen an den gemeinsamen Objekten durch mehrere Prozesse auch durch Semaphore geschützt werden. Schließlich müssen Sie bei der Definition Ihrer Objekte und Datenstrukturen in Offsets vom Anfang des gemeinsamen Speicherbereichs anstelle von absoluten Zeigerwerten denken (es ist im Allgemeinen möglich, dass der Speicher in jedem angeschlossenen Prozess an einer anderen Adresse zugeordnet wird , obwohl Sie bei Bedarf eine feste Zuordnungsadresse auswählen können). Alles in einer robusten Art und Weise zusammenzufassen ist der schwierige Teil. Es ist leicht für gemeinsam genutzte speicherbasierte Datenstrukturen zu korrumpieren, wenn ein Prozess unerwartet abstürzt, daher ist normalerweise ein Mechanismus zur Bereinigung / Wiederherstellung erforderlich.
Untersuchen Sie auch Mutexe und Semaphoren. Wenn zwei oder mehr Entitäten Speicher oder Daten gemeinsam nutzen müssen, muss ein "Verkehrssignal" -Mechanismus vorhanden sein, um den Schreibzugriff auf nur einen Benutzer zu beschränken.
Tags und Links c++ shared-memory memory-management