ein Kapitel zurück                                           ein Kapitel weiter

Kommen wir nun zur schnellsten Methode der IPCs für Prozesse die auf vielen Computer zu finden sind. Das Prinzip ist einfach. Ein Prozess erzeugt einen Shared Memory Bereich und alle anderen können darauf zurückgreifen. Wichtig ist natürlich das sie dafür sorgen das immer nur ein Prozess etwas in diesen Bereich schreibt. Also Synchronisieren. Shared Memory eignen sich prima wenn man mehr Geschwindigkeit für die Zusammenarbeit von Prozessen benötigt die sich auf dem selben Rechner befinden.

Auch bei Shared Memory stehen uns 4 Funktionen zur Verfügung die den von dem Kapitel Message-Queue nicht unähnlich sind.

a) Öffnen bzw. erzeugen eines Shared Memory Bereichs Um einen Shared Memory Bereich zu öffnen oder neu erstellen haben wir die Funktion..........

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, int groesse, int flag);  

Wenn wir einen neuen Shared Memory Speicherbereich einrichten müssen wir einen sogenannten Schlüssel angeben. Dieser Schlüssel hilft uns z.B. wenn ein anderer Prozess die Kennung - ID ,die die Funktion shmget bei Erfolg zurückliefert , nicht kennt trotzdem auf das Objekt zugreifen mit Hilfe des Schlüssels key. Also alle Prozesse die den Schlüssel key kennen können auf auf das Objekt zugreifen das wir mit shmget erzeugen. Folgende Möglichkeiten haben wir einen Schlüssel zu erzeugen.........

  • Mit der Konstante IPC_PRIVATE. Das bedeutet das diesem Objekt kein Schlüssel zugeordnet ist.
  • Wir geben selbst einen Wert eines noch nicht existierenden Schlüssels an. Wichtig ist dabei das sie als flag IPC_CREAT und IPC_EXCL setzen. Denn falls das Objekt schon existiert gibt diese Funktion errno=EEXIST zurück.
  • Wir erzeugen einen Schlüssel mit der Funktion.... key_t ftok(char *pfadname, char projektbezeichner); Diese Funktion wandelt den Pfadnamen einer existierenden Datei zusammen mit dem Projektbezeichner in einem IPC-Schlüssel vom Typ key_t um. (Mehr dazu unter man ftok)

Wollen wir eine Verbindung mit einem bereits existierenden Objekt aufnehmen müssen wir den gleichen Schlüssel verwenden und dürfen als flag auf keinen Fall IPC_CREAT setzen.

Wenn z.B. mehrere verschieden Prozesse auf ein Objekt zugreifen müssen haben sie folgende Möglichkeiten den Schlüssel für diese Prozesse bekannt zu machen.......

  • Sie Speichern diesen in einer Datei
  • Alle Prozesse benutzen die selbe Headerdatei in dem sich dieser Schlüssel befindet.......

    #ifndef _KEY_H_
    #define _KEY_H_
    
    #define UNIVERSAL_KEY 123456
    
    #endif  

Für groesse können sie die minimale Größe des Shared Memorys festlegen. Die Größe errechnet sich dann aus einem Vielfachen von PAGE_SIZE. Ein bereits existierenden Shared Memory Bereich öffnet man mit groesse = 0.

b) Abfragen, Ändern oder Löschen eines Shared Memory Speicherbereich Mit der Funktion...........

int shmctl(int kennungs_id, int kommando, struct shmid_ds *puffer);  

....können sie abhängig vom kommando das Shared-Memory-Segment Ändern, Abfragen oder Löschen. Hier die möglichen angaben für kommando..........

  • IPC_STAT - Status des Shared-Memory-Bereichs
  • IPC_SET - Setzen von Zugriffsrechten
  • IPC_RMID - Löschen des Shared Memory Bereichs
  • SHM_LOCK - Sperren des Shared Memory Bereichs (nur root)
  • SHM_UNLOCK - Aufheben den Sperre (nur root)

Wir befassen aber hier nur das Löschen einer Message Queue. Mehr Informationen zum Abfragen des Status und Änderung des Zugriffsrecht finden sie unter man shmctl und in der Headerdatei <sys/ipc.h> finden sie die Struktur struct msqid_ds ausführlich dokumentiert. Die kennungs_id haben sie als Rückgabewert der Funktion shmget erhalten.

c) Anhängen und Aushängen eines Shared Memory Bereichs an einem Prozess Mit der Funktion.........

void *shmat(int kennungs_id, void *adresse, int flag);  

...können sie an Prozessen dessen kennungs_id sie kennen einen Shared Memory Bereich anhängen. Für die adresse ist es Empfehlenswert einen NULL - Zeiger anzugeben. Damit nimmt Ihnen der Kern die Arbeit ab wo sie den Shared Memory Bereich einhängen. Sollten sie dennoch eine Adresse (Probleme gibt es wenn sie das Programm auf eine anderes System portieren wollen, da auf anderen Systemen die PAGE_SIZE wieder einen anderen Wert hat) eingeben wollen verweise ich sie auf die man-Page dazu.

Um diesen Shared Memory Bereich wieder auszuhängen haben wir die Funktion..........

int shmdt(void *addresse);  

Aushängen heißt aber nicht löschen. Der Shared Memory Bereich existiert noch weiterhin bis sie diesen mit der Funktion shmctl löschen. Bitte beachten sie das bei Linux der Typ von adresse kein void-Zeiger sondern ein char*. Genaueres entnehmen sie auch hier wieder aus der man-Page von shmat und shmdt.

Also gilt für Shared Memory folgender Vorgang (nur ein Beispielsvorgang)......

  • Shared Memory erstellen (shmget)
  • iden Shared Memory Bereich einhängen (attache) (shmat)
  • Jetzt können wir z.B. Daten in diesen Shared Memory Bereich schreiben Andere Prozesse können nun diese Daten lesen, bearbeiten etc. oder auch wieder etwas an andere Prozesse verschicken.
  • Der erstellte Shared Memory Bereich wird wieder ausgehängt (detached) (shmdt)
  • Der Shared Memory Bereich wird gelöscht (shmctl)

Anhand diesem Beispielsvorgang lässt sich erkennen das wir Shared Memory Synchronisieren müssen.

Sollten sie Memory Mapped mit verwandten Prozessen verwenden, so empfielt sich das Kapitel Memory Mapped-i/o anzusehen. Verwenden sie dabei die Datei /dev/zero zur Kommunikation zwischen den Prozessen.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf