Man page - shmat(2)

Packages contains this manual

Available languages:

en fr pl ja ru de

Manual

SHMOP

NOM
BIBLIOTHÈQUE
SYNOPSIS
DESCRIPTION
shmat()
shmdt()
VALEUR RENVOYÉE
ERREURS
STANDARDS
HISTORIQUE
NOTES
EXEMPLES
Source du programme : svshm_string.h
Source du programme : svshm_string_read.c
Source du programme : svshm_string_write.c
VOIR AUSSI
TRADUCTION

NOM

shmat, shmdt - Opérations sur la mémoire partagée System V

BIBLIOTHÈQUE

BibliothĂšque C standard ( libc , -lc )

SYNOPSIS

#include <sys/shm.h>

void *shmat(int shmid , const void *_Nullable shmaddr , int shmflg );
int shmdt(const void *
shmaddr );

DESCRIPTION

shmat()

La fonction shmat () attache le segment de mĂ©moire partagĂ©e System V identifiĂ© par shmid au segment de donnĂ©es du processus appelant. L’adresse d’attachement est indiquĂ©e par shmaddr avec les critĂšres suivants :

-

Si shmaddr vaut NULL, le systÚme choisit une adresse (non utilisée) alignée sur la page convenant pour attacher le segment.

-

Si shmaddr n’est pas NULL et si SHM_RND est indiquĂ© dans shmflg , l’attachement a lieu Ă  l’adresse Ă©gale Ă  shmaddr arrondie au multiple infĂ©rieur de SHMLBA .

-

Sinon, shmaddr doit ĂȘtre alignĂ©e sur une frontiĂšre de page, oĂč l’attachement a lieu.

En plus de SHM_RND , les attributs suivants peuvent ĂȘtre indiquĂ©s dans le paramĂštre de masque shmflg :
SHM_EXEC
(spécifique à Linux, depuis Linux 2.6.9)

Autoriser l’exĂ©cution du contenu du segment. L’appelant doit disposer du droit d’exĂ©cution sur le segment.

SHM_RDONLY

Attacher le segment en lecture seule. Le processus doit disposer de la permission de lecture dessus. Si cet attribut n’est pas indiquĂ©, le segment est attachĂ© en lecture et Ă©criture, et le processus doit disposer des deux permissions d’accĂšs. Il n’y a pas de notion d’écriture seule pour les segments de mĂ©moire partagĂ©e.

SHM_REMAP (spécifique à Linux)

Cet attribut indique que la projection du segment doit remplacer une projection prĂ©cĂ©dente dans l’intervalle commençant en shmaddr et s’étendant sur la taille du segment. Normalement une erreur EINVAL devrait se produire si une projection existe dĂ©jĂ  dans l’intervalle indiquĂ©. Dans ce cas, shmaddr ne doit pas ĂȘtre NULL .

La valeur brk (2) du processus appelant n’est pas altĂ©rĂ©e par l’attachement. Le segment est automatiquement dĂ©tachĂ© quand le processus se termine. Le mĂȘme segment peut ĂȘtre attachĂ© Ă  la fois en lecture seule et en lecture/Ă©criture. Il peut Ă©galement ĂȘtre attachĂ© en plusieurs endroits de l’espace d’adressage du processus.

Quand shmat () réussit, les membres de la structure shmid_ds associée au segment de mémoire partagée (consultez shmctl (2)) sont mis à jour ainsi :

-

shm_atime correspond à l’heure actuelle.

-

shm_lpid contient le PID de l’appelant.

-

shm_nattch est incrémenté de 1.

shmdt()

La fonction shmdt () dĂ©tache le segment de mĂ©moire partagĂ©e situĂ© Ă  l’adresse indiquĂ©e par shmaddr . Le segment doit ĂȘtre effectivement attachĂ©, et l’adresse shmaddr doit ĂȘtre celle renvoyĂ©e prĂ©cĂ©demment par l’appel shmat ().

Quand shmdt () réussit, les membres de la structure shmid_ds associée au segment de mémoire partagée sont mis à jour ainsi par le systÚme :

-

shm_dtime correspond à l’heure actuelle.

-

shm_lpid contient le PID de l’appelant.

-

shm_nattch est dĂ©crĂ©mentĂ© de 1. S’il devient nul et si le segment est marquĂ© pour destruction, il est effectivement dĂ©truit.

VALEUR RENVOYÉE

S’il rĂ©ussit, shmat () renvoie l’adresse d’attachement du segment de mĂ©moire partagĂ©e. En cas d’échec (void *) -1 est renvoyĂ©, et errno est positionnĂ© pour indiquer l’erreur.

S’il rĂ©ussit, shmdt () renvoie 0 . En cas d’échec, -1 est renvoyĂ© et errno est positionnĂ© pour indiquer l’erreur.

ERREURS

shmat () peut échouer avec une des erreurs suivantes :

EACCES

Le processus appelant n’a pas les permissions d’accĂšs nĂ©cessaires pour ce type d’attachement et n’a pas la capacitĂ© CAP_IPC_OWNER dans l’espace de noms utilisateur qui gĂšre son espace de noms IPC.

EIDRM

shmid pointe sur un segment détruit.

EINVAL

La valeur shmid n’est pas valable, mal alignĂ©e (c’est-Ă -dire pas alignĂ©e sur une page et SHM_RND n’a pas Ă©tĂ© prĂ©cisĂ©) ou la valeur shmaddr n’est pas valable, ou ne peut pas ĂȘtre attachĂ© Ă  shmaddr , ou SHM_REMAP a Ă©tĂ© rĂ©clamĂ© et shmaddr est NULL .

ENOMEM

Pas assez de mémoire pour le descripteur ou pour les tables de pages.

shmdt () peut échouer avec une des erreurs suivantes :

EINVAL

Aucun segment de mĂ©moire partagĂ©e n’est attachĂ© Ă  l’adresse shmaddr , ou bien shmaddr n’est pas alignĂ© une limite de page.

STANDARDS

POSIX.1-2008.

HISTORIQUE

POSIX.1-2001, SVr4.

Dans SVID 3 (ou peut ĂȘtre auparavant), le type de l’argument shmaddr a Ă©tĂ© modifiĂ© de char * en const void * , et le type de retour de shmat () de char * en void * .

NOTES

AprĂšs un fork (2), l’enfant hĂ©rite des segments de mĂ©moire partagĂ©e attachĂ©s.

AprÚs un execve (2), tous les segments de mémoire partagée sont détachés du (pas détruits).

Lors d’un _exit (2), tous les segments de mĂ©moire partagĂ©e sont dĂ©tachĂ©s du processus (pas dĂ©truits).

Utiliser shmat () avec shmaddr Ă©gale Ă  NULL est la maniĂšre conseillĂ©e et portable d’attacher un segment de mĂ©moire partagĂ©e. Soyez conscients que le segment attachĂ© de cette maniĂšre peut l’ĂȘtre Ă  des adresses diffĂ©rentes dans les diffĂ©rents processus. Ainsi, tout pointeur contenu dans la mĂ©moire partagĂ©e doit ĂȘtre relatif (habituellement par rapport Ă  l’adresse de dĂ©part du segment) et pas absolu.

Sous Linux, il est possible d’attacher un segment de mĂ©moire partagĂ©e qui est dĂ©jĂ  marquĂ© pour effacement. Cependant, ce comportement n’est pas dĂ©crit par POSIX.1 et beaucoup d’autres implĂ©mentations ne le permettent pas.

Le paramÚtre systÚme suivant influe sur shmat () :

SHMLBA

Multiple d’adresse pour limite basse de segment. Lors d’une indication explicite d’adresse d’attache dans un appel shmat (), l’appelant devrait s’assurer que l’adresse est un multiple de cette valeur. Cela est nĂ©cessaire sur certaines architectures, afin de s’assurer soit de bonne performances du cache de processeur, soit que diffĂ©rentes attaches du mĂȘme segment ont des vues cohĂ©rentes dans le cache du processeur. SHMLBA est normalement un multiple de la taille de page du systĂšme (sur de nombreuses architectures Linux, SHMLBA est identique Ă  la taille de page du systĂšme).

L’implĂ©mentation ne met pas de limite intrinsĂšque par processus pour le nombre maximal de segments de mĂ©moire partagĂ©e ( SHMSEG ).

EXEMPLES

Les deux programmes prĂ©sentĂ©s ci-dessous Ă©changent une chaĂźne en utilisant un segment de mĂ©moire partagĂ©e. Davantage de dĂ©tails Ă  leur sujet sont donnĂ©s ci-dessous. Tout d’abord, nous prĂ©sentons une session d’interprĂ©teur qui montre leur utilisation.

Dans une fenĂȘtre de terminal, nous exĂ©cutons le programme « reader » qui crĂ©e un segment de mĂ©moire partagĂ©e System V et un ensemble de sĂ©maphores System V. Le programme affiche les identifiants des objets créés puis attend que le sĂ©maphore modifie la valeur.

$ ./svshm_string_read
shmid = 1114194; semid = 15

Dans une autre fenĂȘtre de terminal, on exĂ©cute le programme « writer ». Ce programme prend trois paramĂštres en ligne de commande : les identifiants du segment de mĂ©moire partagĂ©e et le jeu de sĂ©maphore, créés par le programme « reader » et une chaĂźne. Il attache le segment de mĂ©moire partagĂ©e existant, copie la chaĂźne dans la mĂ©moire partagĂ©e et modifie la valeur du sĂ©maphore.

$ ./svshm_string_write 1114194 15 'Bonjour'

De retour dans le terminal oĂč s’exĂ©cute « reader », on voit que le programme a cessĂ© d’attendre le sĂ©maphore et affiche la chaĂźne copiĂ©e dans le segment de mĂ©moire partagĂ©e par « writer » :

Bonjour

Source du programme : svshm_string.h

Le fichier d’en-tĂȘte suivant est inclus dans les programmes « reader » et « writer » :

/* svshm_string.h
Sous licence GNU General Public v2 ou postérieure.
*/
#ifndef SVSHM_STRING_H
#define SVSHM_STRING_H
#include <stdio.h>
#include <stdlib.h>
#include <sys/sem.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
union semun { /* Utilisé dans les appels semctl() */
int val;
struct semid_ds *buf;
unsigned short *array;
#if defined(__linux__)
struct seminfo *__buf;
#endif
};
#define MEM_SIZE 4096
#endif // include guard

Source du programme : svshm_string_read.c

Le programme « reader » crĂ©e un segment de mĂ©moire partagĂ©e et un ensemble de sĂ©maphores contenant un sĂ©maphore. Il attache ensuite l’objet en mĂ©moire partagĂ©e Ă  son espace d’adressage et initialise la valeur du sĂ©maphore Ă  1 . Enfin, il attend que la valeur du sĂ©maphore devienne 0 , aprĂšs quoi il affiche la chaĂźne qui a Ă©tĂ© copiĂ©e dans le segment de mĂ©moire partagĂ©e par « writer ».

/* svshm_string_read.c
Sous licence GNU General Public v2 ou postérieure.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "svshm_string.h"
int
main(void)
{
int semid, shmid;
char *addr;
union semun arg, dummy;
struct sembuf sop;
/* Créer la mémoire partagée et le jeu de sémaphores contenant
un sémaphore. */
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");
/*Attacher la mĂ©moire partagĂ©e Ă  notre espace d’adressage. */
addr = shmat(shmid, NULL, SHM_RDONLY);
if (addr == (void *) -1)
errExit("shmat");
/* Initialiser le sémaphore 0 du jeu à la valeur 1 . */
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) == -1)
errExit("semctl");
printf("shmid = %d; semid = %d\n", shmid, semid);
/* Attendre que la valeur du sémaphore devienne 0 . */
sop.sem_num = 0;
sop.sem_op = 0;
sop.sem_flg = 0;
if (semop(semid, &sop, 1) == -1)
errExit("semop");
/* Afficher la chaßne à partir de la mémoire partagée. */
printf("%s\n", addr);
/* Supprimer la mémoire partagée et le jeu de sémaphores. */
if (shmctl(shmid, IPC_RMID, NULL) == -1)
errExit("shmctl");
if (semctl(semid, 0, IPC_RMID, dummy) == -1)
errExit("semctl");
exit(EXIT_SUCCESS);
}

Source du programme : svshm_string_write.c

Le programme « writer » prend trois paramĂštres en ligne de commande : les identifiants du segment de mĂ©moire partagĂ©e et du jeu de sĂ©maphore créés par « reader » et une chaĂźne. Il attache le segment de mĂ©moire partagĂ©e Ă  son espace d’adressage, puis dĂ©crĂ©mente la valeur du sĂ©maphore Ă  0 pour informer « reader » qu’il peut examiner le contenu de la mĂ©moire partagĂ©e.

/* svshm_string_write.c
Sous licence GNU General Public v2 ou postérieure.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include "svshm_string.h"
int
main(int argc, char *argv[])
{
int semid, shmid;
char *addr;
size_t size;
struct sembuf sop;
if (argc != 4) {
fprintf(stderr, "Utilisation : %s shmid semid string\n", argv[0]);
exit(EXIT_FAILURE);
}
size = strlen(argv[3]) + 1; /* +1 pour inclure le '\0' final */
if (size > MEM_SIZE) {
fprintf(stderr, "La chaßne est trop longue !\n");
exit(EXIT_FAILURE);
}
/* Obtenir les identifiants de l’objet depuis la ligne de commande. */
shmid = atoi(argv[1]);
semid = atoi(argv[2]);
/* Attacher la mĂ©moire partagĂ©e dans notre espace d’adressage et copier
la chaĂźne (et notamment l’octet NULL final) dans la mĂ©moire. */
addr = shmat(shmid, NULL, 0);
if (addr == (void *) -1)
errExit("shmat");
memcpy(addr, argv[3], size);
/* Décrémenter le sémaphore à 0 */
sop.sem_num = 0;
sop.sem_op = -1;
sop.sem_flg = 0;
if (semop(semid, &sop, 1) == -1)
errExit("semop");
exit(EXIT_SUCCESS);
}

VOIR AUSSI

brk (2), mmap (2), shmctl (2), shmget (2), capabilities (7), shm_overview (7), sysvipc (7)

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n’y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org .