.\" -*- coding: UTF-8 -*- .\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it) .\" and Copyright 2020 Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\" Modified Sun Nov 28 17:06:19 1993, Rik Faith (faith@cs.unc.edu) .\" with material from Luigi P. Bai (lpb@softint.com) .\" Portions Copyright 1993 Luigi P. Bai .\" Modified Tue Oct 22 22:04:23 1996 by Eric S. Raymond .\" Modified, 5 Jan 2002, Michael Kerrisk .\" Modified, 19 Sep 2002, Michael Kerrisk .\" Added SHM_REMAP flag description .\" Modified, 27 May 2004, Michael Kerrisk .\" Added notes on capability requirements .\" Modified, 11 Nov 2004, Michael Kerrisk .\" Language and formatting clean-ups .\" Changed wording and placement of sentence regarding attachment .\" of segments marked for destruction .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH SHMOP 2 "3. Mai 2023" "Linux man\-pages 6.05.01" .SH BEZEICHNUNG shmat, shmdt \- System\-V\-Operationen mit gemeinsam benutztem Speicher .SH BIBLIOTHEK Standard\-C\-Bibliothek (\fIlibc\fP, \fI\-lc\fP) .SH ÜBERSICHT .nf \fB#include \fP .PP \fBvoid *shmat(int \fP\fIshmid\fP\fB, const void *_Nullable \fP\fIshmaddr\fP\fB, int \fP\fIshmflg\fP\fB);\fP \fBint shmdt(const void *\fP\fIshmaddr\fP\fB);\fP .fi .SH BESCHREIBUNG .SS shmat() \fBshmat\fP() blendet das durch \fIshmid\fP bezeichnete gemeinsame System\-V\-Speichersegment in den Adressraum des aufrufenden Prozesses ein. Die Adresse der Einblendung wird durch \fIshmaddr\fP nach einem der folgenden Kriterien bestimmt: .IP \[bu] 3 Falls \fIshmaddr\fP NULL ist, wählt das System eine geeignete (freie), an einer Speicherseite ausgerichtete Adresse, um das Segment einzublenden. .IP \[bu] Wenn \fIshmaddr\fP nicht NULL ist und \fBSHM_RND\fP in \fIshmflg\fP angegeben wurde, wird die Adresse durch Abrundung von \fIshmaddr\fP bis auf ein Vielfaches von \fBSHMLBA\fP bestimmt. .IP \[bu] Andernfalls muss \fIshmaddr\fP eine an einer Speicherseite ausgerichtete Adresse sein, an welcher das Einblenden beginnt. .PP Zusätzlich zu \fBSHM_RND\fP dürfen die folgenden Schalter im Bitmask\-Argument von \fIshmflg\fP angegeben werden: .TP \fBSHM_EXEC\fP (Linux\-spezifisch; seit Linux 2.6.9) ermöglicht, dass der Inhalt des Segments ausgeführt wird. Der Aufrufende muss auf dem Segment Ausführungsrechte besitzen. .TP \fBSHM_RDONLY\fP blendet das Segment mit Lesezugriff ein. Der Prozess muss die Berechtigung für Lesezugriffe auf das Segment besitzen. Falls dieser Schalter nicht angegeben ist, wird das Segment mit Lese\- und Schreibzugriff 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. .TP \fBSHM_REMAP\fP (Linux\-spezifisch) Dieser Schalter gibt an, dass das Abbilden des Segments jedes existierende Abbilden im Bereich von \fIshmaddr\fP bis zur Größe des Segments ersetzen soll. (Falls bereits eine Abbildung in diesem Adressbereich existiert, würde dies normalerweise zu dem Fehler \fBEINVAL\fP führen.) In diesem Fall darf \fIshmaddr\fP nicht NULL sein. .PP Der \fBbrk\fP(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 in den Adressraum des Prozesses eingeblendet werden. .PP Nach einem erfolgreichen \fBshmat\fP()\-Aufruf aktualisiert das System die Bestandteile der dem Speichersegment zugeordneten \fIshmid_ds\fP\-Struktur (siehe \fBshmctl\fP(2)) wie folgt: .IP \[bu] 3 \fIshm_atime\fP wird auf die aktuelle Zeit gesetzt. .IP \[bu] \fIshm_lpid\fP wird auf die Prozesskennung des aufrufenden Prozesses gesetzt. .IP \[bu] .\" \fIshm_nattch\fP wird um Eins erhöht. .SS shmdt() \fBshmdt\fP() löst das gemeinsame Speichersegment, das an der Adresse \fIshmaddr\fP liegt, aus dem Adressraum des aufrufenden Prozesses. Das zu entfernende gemeinsame Speichersegment muss momentan mit \fIshmaddr\fP eingeblendet sein, das dem Rückgabewert des einbendenden \fBshat\fP()\-Aufrufs entspricht. .PP Nach einem erfolgreichen \fBshmdt\fP()\-Aufruf aktualisiert das System die Bestandteile der dem Speichersegment zugeordneten Struktur \fBshmid_ds\fP wie folgt: .IP \[bu] 3 \fIshm_dtime\fP wird auf die aktuelle Zeit gesetzt. .IP \[bu] \fIshm_lpid\fP wird auf die Prozesskennung des aufrufenden Prozesses gesetzt. .IP \[bu] \fIshm_nattch\fP wird um Eins verringert. Wenn es dabei zu 0 wird und das Segment zum Löschen markiert ist, wird es gelöscht. .SH RÜCKGABEWERT Bei Erfolg gibt \fBshmat\fP() die Adresse des eingeblendeten gemeinsamen Speichersegments zurück; bei einem Fehler wird \fI(void\ *)\ \-1\fP zurückgegeben und \fIerrno\fP gesetzt, um den Fehlers anzuzeigen. .PP Bei Erfolg gibt \fBshmdt\fP() 0 zurück; bei einem Fehler wird \-1 zurückgegeben und \fIerrno\fP gesetzt, um den Fehlers anzuzeigen. .SH FEHLER \fBshmat\fP() kann mit einem der folgenden Fehler fehlschlagen: .TP \fBEACCES\fP Dem aufrufenden Prozess fehlen die nötigen Zugriffsrechte für den angeforderten Einblendetyp und die \fBCAP_IPC_OWNER\fP\-Capability in dem Benutzernamensraum, der seinen IPC\-Namensraum beherrscht. .TP \fBEIDRM\fP \fIshmid\fP zeigt auf einen entfernten Bezeichner. .TP \fBEINVAL\fP Ungültiger \fIshmid\fP\-Wert, nicht ausgerichteter (d.h. nicht an die Seitengröße angepasst und \fBSHM_RND\fP wurde nicht angegeben) oder ungültiger \fIshmaddr\fP\-Wert oder es wurde \fBSHM_REMAP\fP angegeben und \fIshmaddr\fP war NULL. .TP \fBENOMEM\fP Es konnte kein Speicher für den Deskriptor oder die Seitentabellen reserviert werden. .PP \fBshmdt\fP() kann mit einem der folgenden Fehler fehlschlagen: .TP \fBEINVAL\fP .\" The following since Linux 2.6.17-rc1: Es ist kein gemeinsames Speichersegment in \fIshmaddr\fP eingeblendet oder \fIshmaddr\fP ist nicht an der Seitengrenze ausgerichtet. .SH STANDARDS POSIX.1\-2008. .SH GESCHICHTE .\" SVr4 documents an additional error condition EMFILE. POSIX.1\-2001, SVr4. .PP In SVID 3 (oder vielleicht früher) wurde der Typ des Arguments \fIshmaddr\fP von \fIchar\ *\fP in \fIconst void\ *\fP und der von \fBshmat\fP() zurückgegebene Typ von \fIchar\ *\fP in \fIvoid\ *\fP geändert. .SH ANMERKUNGEN Nach einem \fBfork\fP(2) erbt der Kindprozess das eingeblendete gemeinsame Speichersegment. .PP Nach einem \fBexec\fP(2) sind alle eingeblendeten gemeinsamen Speichersegmente vom Prozess abgelöst. .PP Bei einem \fBexit\fP(2) sind alle eingeblendeten gemeinsamen Speichersegmente vom Prozess abgelöst. .PP Die bevorzugte, portierbare Möglichkeit, ein gemeinsames Speichersegment einzublenden, besteht darin, \fBshmat\fP() mit \fIshmaddr\fP 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. .PP Unter Linux ist es möglich, sogar ein gemeinsames Speichersegment einzublenden, wenn es bereits zum Löschen markiert ist. POSIX.1 spezifiziert dieses Verhalten jedoch nicht und andere Implementierungen unterstützen es nicht. .PP Der folgende Systemparameter beeinflusst \fBshmat\fP(): .TP \fBSHMLBA\fP Untere Segmentgrenze des Adressvielfachen. Wenn in einem Aufruf von \fBshmat\fP() eine Adresse explizit angegeben wurde. sollte der Aufrufende sicherstellen, dass die Adresse ein Vielfaches dieses Wertes ist. Dies ist auf einigen Architekturen notwendig, um eine gute Leistung des CPU\-Zwischenspeichers zu gewährleisten oder um sicherzustellen, dass unterschiedliche Einblendungen desselben Segments konsistente Ansichten innerhalb des CPU\-Zwischenspeichers haben. \fBSHMLBA\fP ist normalerweise irgendein Vielfaches von der Seitengröße des Systems. (Auf vielen Linux\-Architekturen ist \fBSHMLBA\fP dasselbe wie die Seitengröße des Systems.) .PP Die Implementierung hat keine inhärenten pro\-Prozess\-Einschränkungen bezüglich der maximalen Anzahl von gemeinsamen Speichersegmenten (\fBSHMSEG\fP). .SH BEISPIELE Die zwei nachfolgend aufgeführten Programme tauschen eine Zeichenkette über ein gemeinsames Speichersegment aus. Weitere Details über die Programme finden Sie nachfolgend. Zuerst wird eine Shell\-Sitzung gezeigt, die ihre Verwendung zeigt. .PP In einem Terminalfenster führen wir das »Lese«\-Programm aus, das ein gemeinsam benutztes Speichersegment und eine Semaphoren\-Gruppe gemäß System\-V erstellt. Das Programm gibt die Kennung der erstellten Objekte aus und wartet dann darauf, dass die Semaphore ihren Wert ändern. .PP .in +4n .EX $ \fB./svshm_string_read\fP shmid = 1114194; semid = 15 .EE .in .PP In einem anderen Terminal\-Fenster führen wir das »Schreibe«\-Programm aus\&. Das »Schreibe«\-Programm akzeptiert drei Befehlszeilenargumente: die Kennungen des vom »Lese«\-Programm erstellten gemeinsam benutzten Speichersegments und die erstellte Semaphoren\-Gruppe und eine Zeichenkette. Es blendet das bestehende gemeinsam benutzte Speichersegment ein, kopiert die Zeichenkette in den gemeinsam benutzten Speicher und verändert den Wert der Semaphore. .PP .in +4n .EX $ \fB./svshm_string_write 1114194 15 \[aq]Hallo, Welt\[aq]\fP .EE .in .PP In dem Terminal\-Fenster, in dem das »Lese«\-Programm läuft, können wir sehen, dass das Programm aufgehört hat, auf die Semaphore zu warten und die Zeichenkette ausgegeben hat, die vom Schreibe\-Programm in den gemeinsam benutzten Speicher kopiert wurde: .PP .in +4n .EX Hallo Welt .EE .in .\" .SS "Quelle des Programms: svshm_string.h" Die folgende Header\-Datei wird von den »Lese«\- und »Schreibe«\-Programmen eingebunden: .PP .in +4n .\" SRC BEGIN (svshm_string.h) .EX /* svshm_string.h \& Lizenziert unter der GNU General Public License v2 oder neuer. */ #include #include #include #include #include #include #include \& #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e } while (0) \& union semun { /* Wird in Aufrufen von semctl() verwandt */ int val; struct semid_ds * buf; unsigned short * array; #if defined(__linux__) struct seminfo * __buf; #endif }; \& #define MEM_SIZE 4096 .EE .\" SRC END .in .\" .SS "Quelle des Programms: svshm_string_read.c" Das »Lese«\-Programm erstellt ein gemeinsam benutztes Speichersegment und eine Semaphore\-Gruppe, die eine Semaphore enthält. Es blendet dann das gemeinsam benutzte Speicherobjekt in seinen Adressraum ein und initialisiert den Semaphoren\-Wert auf 1. Schließlich wartet das Programm darauf, dass der Semaphoren\-Wert 0 wird und gibt danach die Zeichenkette aus, die durch den »Schreiber« in das gemeinsam benutzte Speichersegment kopiert wurde. .PP .in +4n .\" SRC BEGIN (svshm_string_read.c) .EX /* svshm_string_read.c \& Lizenziert unter der GNU General Public License v2 oder neuer. */ #include #include #include #include #include \& #include "svshm_string.h" \& int main(void) { int semid, shmid; char *addr; union semun arg, dummy; struct sembuf sop; \& /* Gemeinsam benutzten Speicher und eine Semaphoren\-Gruppe, die eine Semaphore enthält, erstellen. */ \& shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600); if (shmid == \-1) errExit("shmget"); \& semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600); if (semid == \-1) errExit("semget"); \& /* Gemeinsamen Speicher in unseren Adressraum einblenden. */ \& addr = shmat(shmid, NULL, SHM_RDONLY); if (addr == (void *) \-1) errExit("shmat"); \& /* Semaphore 0 in der Gruppe mit dem Wert 1 initialisieren. */ \& arg.val = 1; if (semctl(semid, 0, SETVAL, arg) == \-1) errExit("semctl"); \& printf("shmid = %d; semid = %d\en", shmid, semid); \& /* Darauf warten, dass der Semaphore\-Wert 0 wird. */ \& sop.sem_num = 0; sop.sem_op = 0; sop.sem_flg = 0; \& if (semop(semid, &sop, 1) == \-1) errExit("semop"); \& /* Die Zeichenkette aus dem gemeinsamen Speicher ausgeben. */ \& printf("%s\en", addr); \& /* Den gemeinsam benutzten Speicher und die Semaphoren\-Gruppe entfernen. */ \& if (shmctl(shmid, IPC_RMID, NULL) == \-1) errExit("shmctl"); if (semctl(semid, 0, IPC_RMID, dummy) == \-1) errExit("semctl"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .in .\" .SS "Quelle des Programms: svshm_string_write.c" Das Schreibe\-Programm akzeptiert drei Befehlszeilenargumente: die Kennungen des vom »Lese«\-Programm bereits erstellten, gemeinsam benutzten Speichersegments und die Sempahoren\-Gruppe und eine Zeichenkette. Es blendet das bestehende gemeinsam benutzte Speichersegment in seinen Adressraum ein, verringert den Semaphoren\-Wert auf 0, um den »Leser« zu informieren, dass er jetzt den Inhalt des gemeinsam benutzten Speichers untersuchen kann. .PP .in +4n .\" SRC BEGIN (svshm_string_write.c) .EX /* svshm_string_write.c \& Lizenziert unter der GNU General Public License v2 oder neuer. */ #include #include #include #include #include \& #include "svshm_string.h" \& int main(int argc, char *argv[]) { int semid, shmid; char *addr; size_t len; struct sembuf sop; \& if (argc != 4) { fprintf(stderr, "Aufruf: %s shmid semid string\en", argv[0]); exit(EXIT_FAILURE); } \& len = strlen(argv[3]) + 1; /* +1, um abschließende »\e0« einzuschließen */ if (len > MEM_SIZE) { fprintf(stderr, "Zeichenkette ist zu groß!\en"); exit(EXIT_FAILURE); } \& /* Objektkennungen von der Befehlszeile erhalten. */ \& shmid = atoi(argv[1]); semid = atoi(argv[2]); \& /* Gemeinsam benutzten Speicher in unseren Adressraum einblenden und Zeichenkette (einschließlich abschließendem Nullbyte) in den Speicher kopieren */ \& addr = shmat(shmid, NULL, 0); if (addr == (void *) \-1) errExit("shmat"); \& memcpy(addr, argv[3], len); \& /* Semaphore auf 0 verringern. */ \& sop.sem_num = 0; sop.sem_op = \-1; sop.sem_flg = 0; \& if (semop(semid, &sop, 1) == \-1) errExit("semop"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .in .SH "SIEHE AUCH" \fBbrk\fP(2), \fBmmap\fP(2), \fBshmctl\fP(2), \fBshmget\fP(2), \fBcapabilities\fP(7), \fBshm_overview\fP(7), \fBsysvipc\fP(7) .PP .SH ÜBERSETZUNG Die deutsche Übersetzung dieser Handbuchseite wurde von Ralf Demmer , Chris Leick und Helge Kreutzmann erstellt. .PP Diese Übersetzung ist Freie Dokumentation; lesen Sie die .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3 .UE oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen. .PP Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die .MT debian-l10n-german@lists.debian.org Mailingliste der Übersetzer .ME .