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.
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.42 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>.