150 likes | 250 Views
C Tutorium – Shared Memory –. Knut Stolze. Shared Memory. Ein Speicherbereich, auf den mehrere Prozesse Zugriff haben Also kein privater Speicher Schnellste Form der Inter-Prozess-Kommunikation (IPC)
E N D
C Tutorium – Shared Memory – Knut Stolze
Shared Memory • Ein Speicherbereich, auf den mehrere Prozesse Zugriff haben • Also kein privater Speicher • Schnellste Form der Inter-Prozess-Kommunikation (IPC) • Shared Memory Segment wird in Adressbereich jedes einzelnen (verbundenen) Prozesses abgebildet
Shared Memory Hauptspeicher Addressraum Prozess 1 Shared Memory Segment Addressraum Prozess 2 Prozess 2 Prozess 1
Gotchas • Zeiger (Pointer) sind Werte, die Adressen zu anderen Daten beinhalten • Shared Memory Segmente können an den unterschiedlichen Adressen in die Adressräume der einzelnen Prozesse abgebildet werden Im Shared Memory darf kein Zeiger hinterlegt werden!!
Erzeugen eines SHM Segments • Ein Prozess legt Segment an int shmget(key, size, flags) • key: Schlüssel für das Segment; üblicherweise mittels “ftok” generiert • size: Größe des Segments in Bytes • Vergleichbar mit Größe bei “malloc” • flags: • IPC_CREAT – Segment erzeugen • IPC_EXCL – zu erzeugendes Segment darf noch nicht existieren; sonst Fehler • Zugriffsrechte (wie bei Dateien) • Ergebnis: ID des Segments (oder –1 bei Fehler) • Nicht gleich dem “key”!
shmget • Es wird keine Verbindung zum SHM hergestellt, d.h. das Segment wird nicht in den aktuellen Prozessraum abgebildet • Windows: • SHM Segment existiert nur so lange, wie der Prozess lebt, der das Segment erzeugt hat
ftok • Generiere Schlüssel für “shmget”, “msgget” oder “semget” key_t ftok(file, proj_id) • file: Existierende Datei (inode kann herangezogen werden) • proj_id: Identifikator für aktuelles Projekt/Programm • Schlüssel ist immer identisch für ein (file, proj_id)-Tupel • Prozessübergreifend • Andere Datei/andere “proj_id” gibt i.A. anderen Schlüssel
Verbinden zu einem existierenden SHM Segment • Jeder Prozess, der auf SHM Segment zugreifen will, muss sich mit dem Segment verbinden void *shmat(id, addr, flags) • id: ID des Shared Memory Segments (von shmget) • addr: Zieladresse des abgebildeten Segments • Sollte immer NULL sein! • flags: • SHM_RDONLY – nur lesender Zugriff möglich • SHM_RND – abrunden einer gegebenen Adresse in “addr” zum nächsten Seitenanfang
shmat • Segment wird in den eigenen Adressraum abgebildet • Ähnlich zu “malloc” • Nach “shmat” kann mit dem Segment wie mit jedem anderen Speicherblock gearbeitet werden • Bei Fehler wird Zeiger mit Wert –1 zurückgegeben ptr = shmat(…); if ((char *)ptr == (char *)(-1)) { … /* Fehler */ … }
Verbindung zum SHM Segment trennen • Aktueller Prozess beendet Verbindung zum Shared Memory Segment int shmdt(addr) • addr: Zeiger zum Beginn des Segments • Ergebnis von “shmat” • Vergleichbar zu “free” • Zugriff auf Speicher des SHM Segments darf nach “shmdt” nicht mehr erfolgen! • Segment wird nicht zerstört
Segment zerstören • Segment wird zum Zerstören markiert int shmctl(id, cmd, buffer) • id: ID des Shared Memory Segments • Ergebnis von “shmget” • cmd: Operation auf dem Segment • IPC_RMID – Segment zerstören • IPC_STAT – Informationen über das Segment in “buffer” kopieren • IPC_SET – Setze Zugriffsrechte für Segment
shmctl • Betriebssystem zestört Segment, wenn letzte Verbindung aller Prozesse getrennt wird • Aktueller Prozess kann immer noch Verbindung haben • Beispiel: Start von X-Server • id = shmget(…, IPC_CREAT | IPC_EXCL) • segment = shmat(id, …) • shmctl(id, IPC_RMID, NULL); • … • shmdt(segment, …)
Verwendung von SHM • Segment ist ein zusammenhängender Speicherbereich • Muss von Anwendung(en) selbständig organisiert und strukturiert werden struct Entry { int x, y; }; ptr = shmat(…); int *count = (int *)ptr; struct Entry *entries = (struct entry *)(count + 1); count entry entry entry … entry
Verwendung von SHM (2) • Konkurrierender Zugriff auf Segment muss synchronisiert werden • Semaphoren • Nur bei Nutzung mehrerer Prozesse • Multi-Threading braucht keinen Shared Memory
Kommandozeile (Unix) • Liste alle IPC-Resources (Message Queues, Semaphore, Shared Memors Segmente) $ ipcs • Lösche eine IPC-Resource $ ipcrm • Beispiel um alle Resources des aktuellen Nutzers zu löschen: $ ipcs | grep `user` | awk ‘{ print “ipcrm –”$1,$2 } | sh -e