pthread_key_create, pthread_key_delete, pthread_setspecific, pthread_getspecific
- Gestion de données spécifiques à un thread
#include <pthread.h>
int pthread_key_create(pthread_key_t *key, void
(*destr_function ) (void *));
int pthread_key_delete(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void
*pointer );
void * pthread_getspecific(pthread_key_t key);
Les programmes ont souvent besoin de variables globales ou statiques ayant
différentes valeurs dans des threads différents. Comme les
threads partagent le même espace mémoire, cet objectif ne peut
être réalisé avec les variables usuelles. Les
données spécifiques à un thread POSIX sont la
réponse à ce problème.
Chaque thread possède un segment mémoire privé, le TSD
(Thread-Specific Data : Données Spécifiques au Thread).
Cette zone mémoire est indexée par des clés TSD. La zone
TSD associe des valeurs du type
void * aux clés TSD. Ces
clés sont communes à tous les threads, mais la valeur
associée à une clé donnée est différente
dans chaque thread.
Pour concrétiser ce formalisme, les zones TSD peuvent être vues
comme des tableaux de pointeurs
void *, les clés TSD comme des
indices entiers pour ces tableaux, et les valeurs des clés TSD comme
les valeurs des entrées correspondantes dans le tableau du thread
appelant.
Quand un thread est créé, sa zone TSD associe initialement NULL
à toutes les clés.
pthread_key_create() alloue une nouvelle clé TSD. Cette clé
est enregistrée à l'emplacement pointée par
clé. Il ne peut y avoir plus de
PTHREAD_KEYS_MAX
clés allouées à un instant donné. La valeur
initialement associée avec la clé renvoyée est NULL dans
tous les threads en cours d'exécution.
Le paramètre
destr_function, si différent de NULL,
spécifie une fonction de destruction associée à une
clé. Quand le thread se termine par
pthread_exit() ou par une
annulation,
destr_function est appelée avec en argument les
valeurs associées aux clés de ce thread. La fonction
destr_function n'est pas appelée si cette valeur est NULL.
L'ordre dans lequel les fonctions de destruction sont appelées lors de
la fin du thread n'est pas spécifiée.
Avant que la fonction de destruction soit appelée, la valeur NULL est
associée à la clé dans le thread courant. Une fonction de
destruction peut cependant réassocier une valeur différente de
NULL à cette clé ou une autre clé. Pour gérer ce
cas de figure, si après l'appel de tous les destructeurs pour les
valeurs différentes de NULL, il existe toujours des valeurs
différentes de NULL avec des destructeurs associés, alors la
procédure est répétée. L'implémentation de
LinuxThreads interrompt cette procédure après
PTHREAD_DESTRUCTOR_ITERATIONS itérations, même s'il reste
des valeurs différentes de NULL associées à des
descripteurs. Les autres implémentations peuvent boucler sans fin.
pthread_key_delete() désalloue une clé TSD. Elle ne
vérifie pas si des valeurs différentes de NULL sont
associées avec cette clé dans les threads en cours
d'exécution, ni n'appelle la fonction de destruction associée
avec cette clé.
pthread_setspecific() change la valeur associée avec
clé dans le thread appelant, sauve le paramètre
pointer à sa place.
pthread_getspecific() renvoie la valeur actuellement associée avec
clé dans le thread appelant.
pthread_key_create(),
pthread_key_delete() et
pthread_setspecific() renvoient 0 en cas de succès et un code
d'erreur non nul en cas d'échec. En cas de succès,
pthread_key_create() enregistre la clé récemment
créée à l'emplacement pointé par son argument
clé.
pthread_getspecific() renvoie la valeur associée à
clé en cas de succès et NULL en cas d'erreur.
pthread_key_create() renvoie le code d'erreur suivant :
- EAGAIN
-
PTHREAD_KEYS_MAX clés sont déjà
allouées.
pthread_key_delete() et
pthread_setspecific() renvoient le code
d'erreur suivant :
- EINVAL
-
clé n'est pas une clé TSD
allouée valable.
pthread_getspecific() renvoie NULL si
clé n'est pas une
clef TSD allouée valable.
Xavier Leroy <
[email protected]>
pthread_create(3),
pthread_exit(3),
pthread_testcancel(3).
L'extrait de code suivant alloue dans un thread un tableau de 100
caractères, avec libération de la mémoire automatiquement
à la fin de l'exécution du thread.
/* Clé pour le tampon spécifique au thread */ static pthread_key_t buffer_key;
/* Initialisation unique de la clé */ static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
/* Alloue le tampon spécifique au thread */ void buffer_alloc(void) { pthread_once(&buffer_key_once, buffer_key_alloc); pthread_setspecific(buffer_key, malloc(100)); }
/* Renvoie le tampon spécifique au thread */ char * get_buffer(void) { return (char *) pthread_getspecific(buffer_key); }
/* Alloue la clé */ static void buffer_key_alloc() { pthread_key_create(&buffer_key, buffer_destroy); }
/* Libère le tampon spécifique au thread */ static void buffer_destroy(void * buf) { free(buf); }
La traduction française de cette page de manuel a été
créée par Gérard Delafond <
[email protected]>,
Christophe Blaess <
[email protected]>, Thierry Vignaud
<
[email protected]>, Alain Portal <
[email protected]>,
Denis Barbier <
[email protected]>, Nicolas François
<
[email protected]>, Florentin Duneau
<
[email protected]>, Thomas Blein <
[email protected]> et David
Prévot <
[email protected]>
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 à
[email protected]