Linked list in shared memory



  • Hallo zusammen,

    ich habe aktuell ein Programm welches eine linked list aufbaut, sich forked und dann auf den Child Prozess wartet. In dem Child Prozess wird diese linked list benutzt. Diese linked list wird mit Hilfe von malloc dynamisch aufgebaut.
    So weit so gut. Jetzt muss, aus diversen Gründen, der Code aus dem Fork in ein eigenes Programm ausgelagert werden, welches dann im fork mit einem execl aufgerufen wird.

    Meine erste Idee war die liste einfach in eine shared memory Datei zu legen und dann im child Prozess diese zu mappen und gut ist. Was ich nicht bedacht habe ist, dass man dann ja keine absoluten Pointer mehr benutzen kann. Wenn alle Datentypen in dem Node der Liste statisch wären ginge es auch noch, nur sind davon einige dynamisch und müssten es auch bleiben:

    typedef struct {
        int type;
        int array_type;
        int length; 
        void *value;
    } RH4nVarObj;
    
    typedef struct RH4nVarEntry_s {
        char *name;
        RH4nVarObj var;
        struct RH4nVarEntry_s *prev;
        struct RH4nVarEntry_s *next;
        struct RH4nVarEntry_s *nextlvl;
    } RH4nVarEntry_t;
    

    Die Pointer auf prev, next und nextlvl könnte man zwar mit einem Integer, welcher als index dient, ersetzten und dann die ganze linked List in ein Array legen, löst aber nicht das Problem das zumindest value dynamisch bleiben muss.

    Gibt es noch andere Möglichkeiten unter Linux oder ist shared memory schon die beste Lösung? Falls ja wie könnte es funktionieren?



  • Wenn man anstatt Memory Mapped Files SYSV bzw. XSI Shared Memory verwendet, kann man die Adressen in allen Prozessen auf die gleiche Adresse legen.



  • In der Theorie könnte dies funktionieren. Leider kenne ich vor Erstellung der Liste die komplette Größe nicht und so wie ich es sehe kann man shared memory so ohne weiteres nicht vergrößern.



  • Dann werden Sie wohl eine eigene Speicherverwaltung auf dem Shared Mem schreiben müssen, und ggf. weitere Blöcke anfordern müssen.



  • Naja du könntest das Shared Memory mit einer ausreichend grossen Fixgrösse anlegen, und dann Offsets statt Zeiger speichern. (Entweder Offsets zum Anfang des Shared-Memory Bereichs, oder, vermutlich einfacher, den Offset zu der Adresse wo der Offset gespeichert ist.)
    Auf jeden Fall wirst du dabei aber nicht um die Verwaltung einer eigenen Free-List herumkommen - inklusive Synchronisierung wenn mehr als nur ein Prozess darauf zugreift.

    Gerade auf Linux sollte das, also das Anfordern eines sehr grossen Speicherblocks, relativ egal sein, da Linux ja beim committen nicht wirklich committet.