thread

Section spécifique à Microsoft

Le modificateur de classe de stockage étendu thread permet de déclarer une variable locale de thread. Pour l’équivalent portable en C++11 et versions ultérieures, utilisez le spécificateur de classe de stockage thread_local pour le code portable. Sur Windows, thread_local est implémenté avec __declspec(thread).

Syntaxe

__declspec(thread) déclarateur

Notes

Le stockage local des threads (TLS) est le mécanisme par lequel chaque thread d’un processus multithread alloue de l’espace de stockage pour les données spécifiques aux threads. Dans les programmes multithread standard, les données sont partagées entre tous les threads d’un processus donné, alors que le stockage local des threads est le mécanisme d’allocation des données par thread. Pour une description complète des threads, reportez-vous à Multithreading.

Les déclarations de variables de thread locales doivent utiliser la syntaxe à attributs étendus et le mot clé __declspec avec le mot clé thread. Par exemple, le code suivant déclare une variable locale de thread entière et lui affecte une valeur initiale :

__declspec( thread ) int tls_i = 1;

Lorsque vous utilisez des variables locales thread dans des bibliothèques chargées dynamiquement, vous devez connaître les facteurs qui peuvent entraîner l’initialisation correcte d’une variable locale thread :

  1. Si la variable est initialisée avec un appel de fonction (y compris les constructeurs), cette fonction est appelée uniquement pour le thread qui a provoqué le chargement du fichier binaire/DLL dans le processus et pour les threads qui ont démarré après le chargement du fichier binaire/DLL. Les fonctions d’initialisation ne sont pas appelées pour un autre thread qui était déjà en cours d’exécution lors du chargement du DLL. L’initialisation dynamique se produit lors de l’appel de DllMain pour DLL_THREAD_ATTACH, mais le DLL ne reçoit jamais ce message s’il n’est pas dans le processus au démarrage du thread.

  2. Les variables locales thread qui sont initialisées statiquement avec des valeurs constantes sont généralement initialisées sur tous les threads. Toutefois, à compter de décembre 2017, il existe un problème de conformité connu dans le compilateur Microsoft C++ qui fait que les variables constexpr reçoivent une initialisation dynamique plutôt que statique.

    Remarque : ces deux problèmes devraient être résolus dans les futures mises à jour du compilateur.

En outre, vous devez respecter ces indications lorsque vous déclarez des variables et des objets locaux de thread :

  • Vous pouvez appliquer l'attribut thread uniquement aux déclarations et définitions de classes et de données. L'attribut thread ne peut pas être utilisé sur des définitions ou déclarations de fonctions.

  • Vous pouvez spécifier l'attribut thread uniquement pour les éléments de données ayant une durée de stockage statique. Cela concerne notamment les objets de données globaux (static et extern), les objets statiques locaux et les membres de données statiques des classes. Vous ne pouvez pas déclarer d'objets de données automatiques à l'aide de l'attribut thread.

  • Vous devez utiliser l’attribut thread pour la déclaration et la définition d’un objet local de thread, que la déclaration et la définition se produisent dans le même fichier ou dans des fichiers séparés.

  • Vous ne pouvez pas utiliser l’attribut thread comme modificateur de type.

  • Dans la mesure où la déclaration d'objets utilisant l'attribut thread est autorisée, ces deux exemples sont équivalents sur le plan sémantique :

    // declspec_thread_2.cpp
    // compile with: /LD
    __declspec( thread ) class B {
    public:
       int data;
    } BObject;   // BObject declared thread local.
    
    class B2 {
    public:
       int data;
    };
    __declspec( thread ) B2 BObject2;   // BObject2 declared thread local.
    
  • Le langage C standard permet l'initialisation d'un objet ou d'une variable à l'aide d'une expression impliquant une auto-référence, mais uniquement pour les objets non statiques. Même si C++ admet normalement l’initialisation dynamique d’un objet à l’aide d’une référence impliquant une auto-référence, ce type d’initialisation n’est pas permis avec les objets locaux de thread. Par exemple :

    // declspec_thread_3.cpp
    // compile with: /LD
    #define Thread __declspec( thread )
    int j = j;   // Okay in C++; C error
    Thread int tls_i = sizeof( tls_i );   // Okay in C and C++
    

    Une expression sizeof comprenant l'objet initialisé ne constitue pas une auto-référence. Elle est autorisée en C et en C++.

FIN de la section spécifique à Microsoft

Voir aussi

__declspec
Mots clés
Stockage local des threads (TLS)