SHMOP(2)

BEZEICHNUNG
shmat, shmdt - Operationen mit gemeinsam benutztem Speicher

ÜBERSICHT
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);

BESCHREIBUNG
shmat() blendet das durch shmid bezeichnete gemeinsame Speichersegment in den Adressraum des aufrufenden Prozesses ein. Die Adresse der Enblendung wird durch shmaddr nach einem der folgenden Kriterien bestimmt:

Falls shmaddr NULL ist, wählt das System eine geeignete (freie) Adresse, an der das Segment eingeblendet wird.

Wenn shmaddr nicht NULL ist und SHM_RND in shmflg angegeben ist, wird die Adresse durch Abrundung von shmaddr als Vielfaches von SHMLBA bestimmt. Andernfalls muss shmaddr eine an einer Speicherseite ausgerichtete Adresse sein, an welcher das Einblenden beginnt.

Ist SHM_RDONLY in shmflg gesetzt, wird das Segment zum Lesen eingeblendet und der Prozess muss die Berechtigung für Lesezugriffe auf das Segment besitzen. Andernfalls wird das Segment zum Lesen und Schreiben eingeblendet und der Prozess muss die Berechtigung für Lese- und Schreibzugriffe auf das Segment besitzen. Ein gemeinsames Speichersegment mit reinem Schreibzugriff ist nicht vorgesehen.

Mit dem (Linux-spezifischen) Schalter SHM_REMAP in shmflag können Sie bestimmen, dass das Abbilden des Segments jede vorhandene Abbildung im Bereich von shmaddr bis zum Ende des Segments ersetzt. (Falls bereits eine Abbildung in diesem Adressbereich existiert, würde dies normalerweise zu dem Fehler EINVAL führen.) In diesem Fall darf shmaddr nicht NULL sein.

Der brk(2)-Wert des aufrufenden Prozesses wird durch das Einblenden nicht verändert. Das Segment wird bei Beenden des Prozesses automatisch abgetrennt. Das gleiche Segment kann mit Lese- sowie mit Lese- und Schreibzugriff einmal oder mehrfach an den Adressraum des Prozesses eingeblendet werden.

Nach einem erfolgreichen shmat()-Aufruf aktualisiert das System die Bestandteile der dem Speichersegment zugeordneten shmid_ds-Struktur (siehe shmctl(2)) wie folgt:

    shm_atime wird auf die aktuelle Zeit gesetzt.

    shm_lpid wird auf die Prozess-ID des aufrufenden Prozesses gesetzt.

    shm_nattch wird um eins erhöht.

shmdt() löst das gemeinsame Speichersegment, das an der Adresse shmaddr liegt aus dem Adressraum des aufrufenden Prozesses. Das zu entfernende gemeinsame Speichersegment muss momentan mit shmaddr eingeblendet sein, das dem Rückgabewert des einbendenden shat()-Aufrufs entspricht.

Nach einem erfolgreichen shmdt()-Aufruf aktualisiert das System die Bestandteile der dem Speichersegment zugeordneten Struktur shmid_ds wie folgt:

    shm_dtime wird auf die aktuelle Zeit gesetzt.

    shm_lpid wird auf die Prozess-ID des aufrufenden Prozesses gesetzt.

    shm_nattch wird um eins verringert. Wenn es dabei zu 0 wird und das Segment zum Löschen markiert ist, wird es gelöscht.

Nach einem fork(2) erbt der Kindprozess das eingeblendete gemeinsame Speichersegment. Nach einem exec(2) sind alle eingeblendeten gemeinsamen Speichersegmente vom Prozess abgelöst. Bei einem exit(2) sind alle eingeblendeten gemeinsamen Speichersegmente vom Prozess abgelöst.

RÜCKGABEWERT
Bei Erfolg gibt shmat() die Adresse des eingeblendeten gemeinsamen Speichersegments zurück; bei einem Fehler wird (void *) -1 zurückgegeben und errno so gesetzt, dass es den Grund des Fehlers anzeigt. Bei Erfolg gibt shmdt() 0 zurück; bei einem Fehler wird -1 zurückgegeben und errno so gesetzt, dass es den Grund des Fehlers anzeigt.

FEHLER
Wenn shmat fehlschlägt, wird errno mit einem der folgenden Werte belegt:

EACCES
    Dem aufrufenden Prozess fehlen die nötigen Zugriffsrechte für den angeforderten Einblendetyp und die CAP_IPC_OWNER-Fähigkeit.

EINVAL
    ungültiger shmid-Wert, nicht ausgerichteter (d.h. nicht an die Seitengröße angepasst und SHM_RND wurde nicht angegeben) oder ungültiger shmaddr-Wert oder es wurde SHM_REMAP angegeben und shmaddr war NULL.

ENOMEM
    Es konnte kein Speicher für den Deskriptor oder die Seitentabellen reserviert werden.

Wenn shmat() fehlschlägt, ist errno mit einem der folgenden Werte belegt:

EINVAL
    Es ist kein gemeinsames Speichersegment an shmaddr eingeblendet oder shmaddr ist nicht an der Seitengrenze ausgerichtet.

KONFORM ZU
SVr4, POSIX.1-2001. In SVID 3 (oder vielleicht früher) wurde der Typ des Arguments shmaddr von char * in const void * und der von shmat() zurückgegebene Typ von char * in void * geändert. (Linux-Libc4 und -Libc5 haben die char *-Prototypen, Glibc2 hat void *.)

ANMERKUNGEN
Die bevorzugte, portierbare Möglichkeit ein gemeinsames Speichersegment einzublenden besteht darin, shmat() mit shmaddr gleich NULL zu benutzen. Sie sollten wissen, dass das eingeblendete gemeinsame Speichersegment auf diese Art an unterschiedliche Adressen in unterschiedlichen Prozessen eingeblendet werden kann. Deshalb müssen alle innerhalb des gemeinsamen Speichers verwalteten Zeiger relativ (typischerweise zur Startadresse des Segments) statt absolut sein.

Auf Linux ist es möglich, sogar ein gemeinsames Speichersegment einzublenden, wenn es bereits zum Löschen markiert ist. POSIX.1-2001 spezifiziert dieses Verhalten jedoch nicht und andere Implementierungen unterstützen es nicht.

Der folgende Systemparameter beeinflusst shmat():

SHMLBA
    Adress-Multiplikator der Segmentuntergrenze. Muss seitenkonform sein. In der aktuellen Implemtentierung ist der Wert von SHMBLA gleich PAGE_SIZE.

Die Implemtentierung hat keinen wesentlichen Einschränkungen der maximalen Anzahl von gemeinsamen Speichersegmenten pro Prozess (SHMSEG)

SIEHE AUCH
brk(2), mmap(2), shmctl(2), shmget(2), capabilities(7), shm_overview(7), svipc(7)

KOLOPHON
Diese Seite ist Teil der Veröffentlichung 3.27 des Projekts Linux-man-pages. Eine Beschreibung des Projekts und Informationen, wie Fehler gemeldet werden können, finden sich unter http://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Ralf Demmer <rdemmer@rdemmer.de> und Chris Leick <c.leick@vollbio.de> erstellt. Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen. Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an <debian-l10n-german@lists.debian.org>.