Movatterモバイル変換


[0]ホーム

URL:


Aller au contenu
Wikipédial'encyclopédie libre
Rechercher

Thread Local Storage

Un article de Wikipédia, l'encyclopédie libre.

LeThread Local Storage (TLS), oumémoire locale de thread, est un type demémoire spécifique etlocale à unthread.

Ce mécanisme est parfois requis parce que tous les threads d'un mêmeprocessus partagent le mêmeespace d'adressage. Donc, les données situées dans unevariablestatique ouglobale sont exactement au même emplacement mémoire pour tous les threads, et correspondent donc à la même entité.

Lesvariables sur lapile sont toutefoislocales au thread, parce que chaque thread possède sa propre pile, distincte de celle des autres threads.

Cependant, il est parfois utile que deux threads puissent référencer la même variable « globale » tout en possédant chacun une copie distincte, donc à des adresses mémoire différentes. Ceci rend la variable « locale » au thread, tout en ayant une syntaxe d'utilisation identique à celle d'une variable globale. Un exemple trivial d'une telle variable est, par exemple, la variableerrno dulangage C.

S'il est possible de rendre au minimum unpointeur local aux threads, alors il est possible de créer pour chaque thread du système une zone mémoire de taille arbitraire contenant des données locales de thread.En effet, cette zone peut elle-même être un simpletableau de pointeurs, ce qui permet ensuite (par déréférencements successifs) d'obtenir unTLS de taille totalement arbitraire, quelle que soit la limite initiale de la zone.

Illustration

[modifier |modifier le code]
Principe générique du TLS

Le processus possède ici deux threads. On alloue deux slots du TLS : le premier pour stocker un entier (index 2), le second pour stocker un pointeur (index 4), en bleu clair.Chaque thread va alors obtenir une zone mémoire privée (parties vert sombre pour le thread 1, bleu sombre pour le thread 2), permettant d'accéder à sa donnée locale, éventuellement via une indirection pour le pointeur, tout en n'utilisant qu'un index global et identique entre les deux (simplification du code).

Implémentations dépendantes du système d'exploitation

[modifier |modifier le code]

Implémentation sous Windows

[modifier |modifier le code]

Dans l'APIWindows[1], on utilise le termeTLS.

LafonctionTlsAlloc est utilisée pour obtenir unindex de slot TLS inutilisé - en pratique, le premier disponible - qui sera ensuite réservé jusqu'à la fin du processus ou la libération duTLS. Un seul thread doit appeler cette fonction : par la suite, seul l'index retourné est utilisé. Cette opération est bien entendu totalement atomique. On fournit en général ensuite cet index aux threads soit via une variable globale (accédée en lecture seule par les threads), soit dans les paramètres de création du thread (solution préférable).L'index retourné est un entier, mais ne doit pas être considéré comme un indice de tableau. Il est nécessaire de le traiter comme untype opaque.

Les fonctionsTlsGetValue etTlsSetValue sont ensuite utilisées pour (respectivement) lire et écrire une variableTLS, identifiée par sonindex de slot TLS. Cette variable est un pointeur non-typé, dont l'usage est libre, et qui sera propre à chaque thread. Toutefois, tout thread est responsable de l'allocation des données ciblées par ce pointeur.
On peut noter que la taille de ce pointeur est dépendante de l'architecture Windows courante (32 bits ou64 bits), et qu'il n'est pas contre-indiqué d'utiliser le slot pour stocker une variable quelconque, de taille inférieure ou égale à celle du pointeur, en lieu et place d'un pointeur.
Ceci recouvre notamment le cas d'un entier : c'est ainsi que l'API Windows stocke le dernier code d'erreur obtenu parGetLastError, par exemple.

La fonctionTlsFree peut être utilisée pour libérer l'index de slot TLS passé en paramètre. L'index est ensuite considéré de nouveau comme « inutilisé », et pourra être réattribué par la suite. Il est donc crucial d'être certain, lors de la libération, qu'il n'existe plus aucun thread utilisant cetindex TLS.

Implémentation sous Pthreads (Linux)

[modifier |modifier le code]

Dans l'APIPthreads[2], on utilise le terme TSD (Thread-Specific Data) pour désigner leTLS.

Le principe est similaire à celui utilisé sous Windows, seuls les noms des fonctions changent :

  1. pthread_key_create est équivalent àTlsAlloc.
  2. pthread_getspecific est équivalent àTlsGetValue.
  3. pthread_setspecific est équivalent àTlsSetValue.
  4. pthread_key_delete est équivalent àTlsFree.
  5. Laclé (key) est équivalent à l'index de slot TLS, mais est définie via un type explicitement opaquepthread_key_t.

La seule différence réelle entre les deux systèmes est quepthread_key_create permet de définir undestructeur optionnel qui sera appelé automatiquement à la fin du thread. Chaque destructeur recevra, en paramètre, le contenu stocké dans la clé associée, permettant ainsi d'effectuer la libération des ressources associées.

L'utilisation de ce destructeur ne dispense pas d'appeler explicitementpthread_key_delete pour libérer leTSD lui-même, au niveau du processus. Le destructeur ne permet que la libération des données locales au thread.

Implémentations spécifiques

[modifier |modifier le code]

En plus de la possibilité d'appeler les fonctions natives dusystème d'exploitation décrites ci-dessus, certainslangages oucompilateurs permettent d'utiliser une fonctionnalité équivalente, voire identique, auTLS de façon plus simple et/ou plus pratique que faire appel auxprimitives système.

Compilateurs etIDE

[modifier |modifier le code]

Visual C++ et Intel C++ Compiler (Windows)

[modifier |modifier le code]

Lemot-clé__declspec(thread) est utilisé en préfixe de déclaration :

intvariable_globale;__declspec(thread)intvariable_TLS;

La variableTLS est ensuite utilisable de façon tout à fait normale.

Sun Studio,IBM XL C/C++ etIntel C++ Compiler (Linux)

[modifier |modifier le code]

Le mot-clé__thread est utilisé en préfixe de déclaration :

intvariable_globale;__threadintvariable_TLS;

La variableTLS est ensuite utilisable de façon tout à fait normale.

Digital Mars C++

[modifier |modifier le code]

Le mot-clé__declspec(thread) est utilisé en préfixe de déclaration :

intvariable_globale;__declspec(thread)intvariable_TLS;

La variableTLS est ensuite utilisable de façon tout à fait normale.

Borland C++ Builder (Windows)

[modifier |modifier le code]

Le mot-clé__declspec(thread) est utilisé en préfixe de déclaration :

intvariable_globale;__declspec(thread)intvariable_TLS;

Le mot-clé__thread est une alternative de déclaration, mais entre le type et l'identifiant :

intvariable_globale;int__threadvariable_TLS;

Dans les deux cas, la variableTLS est ensuite utilisable de façon tout à fait normale.

GCC/G++

[modifier |modifier le code]

Le mot-clé__thread est utilisé en préfixe de déclaration, mais est implémenté de façon particulière :

intvariable_globale;__threadintvariable_TLS=1;

Toutefois, la variableTLS doit impérativement être initialisée avec une constante connue au moment de la compilation (cas de l'exemple ci-dessus).

Il n'est pas autorisé de déclarer une variableTLS sans initialisation, ou étant initialisée par un paramètre et/ou un appel de fonction.

C++11

[modifier |modifier le code]

Depuis la norme C++11, le langage fournit la classe de stockagethread_local.

Comme pour les implémentations spécifiques aux compilateurs, le mot-clé est utilisé en préfixe de déclaration :

intvariable_global;thread_localintvariable_TLS;

Langages

[modifier |modifier le code]

Delphi etFree Pascal

[modifier |modifier le code]

Le mot-cléThreadVar est utilisé en lieu et place du traditionnelVar pour déclarer une variableTLS.

Varvariable_globale:Integer;ThreadVarvariable_TLS:Integer;

La variableTLS est ensuite utilisable de façon tout à fait normale.

Java

[modifier |modifier le code]

En Java, les variablesTLS sont implémentées au travers de laclasseThreadLocal(en). Un objetThreadLocal maintient une instance séparée de la variable pour chaque thread appelant lesaccesseurs de l'objet (get etset).

L'exemple ci-dessous montre comment créer une variable entièreTLS :

ThreadLocal<Integer>variable_TLS=newThreadLocal<Integer>(){@OverrideprotectedIntegerinitialValue(){return1;}};

L'utilisation de la variable se fait au travers des accesseurs. Par exemple, une incrémentation :

variable_TLS.set(variable_TLS.get()+1);

D

[modifier |modifier le code]

En D (version 2), toutes les variables statiques et globales sont, par défaut, locales aux threads et sont déclarées comme les variables « normales » des autres langages.C'est la déclaration explicite d'une variable globale « partagée » qui requiert l'utilisation d'un mot-clé spécifique,__gshared.

intvariable_TLS;__gsharedintvariable_globale;

La variableTLS est ensuite utilisable de façon tout à fait normale, ainsi que la variable globale déclarée explicitement.

C# et langages.NET

[modifier |modifier le code]

On utilise l'attributThreadStatic(en) :

classclasse_avec_TLS{[ThreadStatic]staticintvariable_TLS;}

Également, on peut allouer dynamiquement des variablesTLS via l'APIThread.GetNamedDataSlot(en).

La variableTLS est ensuite utilisable de façon tout à fait normale.

Python

[modifier |modifier le code]

En Python (version 2.4 ou supérieure), on utilise la classelocal du modulethreading pour définir une variableTLS.

importthreadingvariable_TLS=threading.local()variable_TLS.x=1

La variableTLS est ensuite utilisable de façon tout à fait normale.

Ruby

[modifier |modifier le code]

En Ruby, une variableTLS est créée et utilisée grâce aux méthodes[]=/[].

Thread.current[:index_TLS]=1

Perl

[modifier |modifier le code]

Le support des threads n'est arrivé que tardivement dans le langage Perl, après qu'une vaste quantité de code source fut présente surComprehensive Perl archive network. En conséquence de ceci, les threads en Perl créent par défaut leur propreTLS pour toutes les variables, de façon à minimiser l'impact des threads sur le code existant nonthread-safe.En Perl, une variable partagée entre les threads (cas « normal » dans les autres langages) est créée en utilisant un attribut :

usethreads;usethreads::shared;my$variable_TLS;my$variable_globale:shared;

Liens externes

[modifier |modifier le code]

Références

[modifier |modifier le code]
  1. Thread Local Storage onMSDN Library(en)
  2. manpage PTHREAD_SPECIFIC onLinux manpages(en)
v ·m
Principes de base
Patrons de conception
Problèmes classiques
v ·m
Noyaux courants
Autres noyaux
Multitâche
Matériel
Mémoire
Technique
Ce document provient de « https://fr.wikipedia.org/w/index.php?title=Thread_Local_Storage&oldid=169803179 ».
Catégories :
Catégories cachées :

[8]ページ先頭

©2009-2026 Movatter.jp