2013-05-07 4 views
11

Ich habe eine C++ - Anwendung, die Shared Memory auf einem Linux-System über Shmget (2) zuweist. Die Daten, die ich im Shared Memory speichere, wachsen periodisch, und ich möchte die Größe des Shared Memory auf eine Weise ändern, die der Art entspricht, wie realloc() regulären Speicher anwächst. Gibt es eine Möglichkeit, dies zu tun? Ich habe ein Dokument auf der IBM Website gefunden, das einen SHM_SIZE-Befehl erwähnt, aber die Linux- und BSD-Hilfeseiten haben es nicht, selbst in den Linux-spezifischen Abschnitten.Kann ich Linux Shared Memory mit shmctl ändern?

+0

als eine Inspiration, siehe: http://www.boost.org/doc/libs/1_61_0/doc/html/interprocess/quick_guide.html - speziell 'gemanaged_shared_memory', die verwendet werden kann, um ein' zu halten vector' in shared memory ... – Nim

Antwort

5

Einfache Antwort: Es gibt keinen einfachen Weg.

Die Gründe sind ziemlich logisch. Shared Memory wird an den virtuellen Raum jedes Prozesses einzeln angehängt. Jeder Prozess hat seinen eigenen virtuellen Adressraum. Jeder Prozess ist frei, das Segment bei jedem anzuhängen (nicht wörtlich, Ausrichtung setzt einige Einschränkungen) beliebige Adresse. Wie kann System garantieren, dass, sagen wir durch Erweiterung Bereich von 4MiB, jeder "Benutzer" dieses Segments in der Lage sein wird, Bigget Block unter der gleichen Startadresse wo das kleinere Segment zuvor war?

Aber Sie sollten nicht aufgeben! Sie können kreativ sein. Sie können die Idee haben, ein Header Segment, wo Sie Informationen über echte Nutzlast-Segment speichern. Sie können jeden Prozess dazu bringen, einige Regeln zu befolgen, wie zum Beispiel: Nutzdatensegment wieder anbringen, wenn seine ID, wie irgendwo in Header-Segment beschrieben, nicht die bekannte entspricht.

Der Rat: Ich vermute, Sie wissen das, aber nie Zeiger auf Daten innerhalb gemeinsam genutzter Bereich halten, Offset nur.

Ich hoffe, dass Sie etwas von meinem Kauderwelsch verwenden.

+0

Danke - das ist sehr hilfreich! –

0

Es scheint für mich, dass Sie Ihren eigenen Speichermanager für Ihren Zweck schreiben können. Die Konzeption ist recht einfach:

  1. Sie haben einen gemeinsamen Speicherblock, dessen Größe N Bytes ist;
  2. Neuer Block für gemeinsam genutzten Speicher mit 2*N Größe zuweisen;
  3. Kopieren Sie Speicher von einem Block zum anderen;
  4. Geben Sie den alten freigegebenen Speicherblock frei;
  5. Wickeln Sie die # 2-4 in eine Routine und verwenden Sie es;

Ich fürchte, wir haben nichts mehr damit zu tun. So ist std::vector implementiert. Und void *realloc() in den meisten Fällen wird Ihnen den Zeiger auf den neuen Speicherblock zurückgeben (aber nicht auf den erweiterten alten Block).

+0

Ich glaube, so zu tun, wird 'shared' Eigenschaft dieser Art von Speicher nicht existent machen. – GreenScape