thread

Section spécifique à Microsoft

Le thread modificateur de classe de stockage étendu est utilisé pour 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)declarator

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 discussion complète sur les threads, consultez Multithreading.

Les déclarations de variables locales de thread doivent utiliser la syntaxe d’attribut étendue et la __declspec mot clé avec le thread mot clé. 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 de 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 de 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 de la DLL. L’initialisation dynamique se produit sur l’appel DllMain pour DLL_THREAD_ATTACH, mais la DLL n’obtient jamais ce message si la DLL n’est pas dans le processus au démarrage du thread.

  2. Les variables locales de thread qui sont initialisées statiquement avec des valeurs constantes sont généralement initialisées correctement sur tous les threads. Toutefois, à compter de décembre 2017, il existe un problème de conformité connu dans le compilateur Microsoft C++ dans lequel constexpr les variables 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 observer ces instructions lors de la déclaration d’objets et de variables locaux de thread :

  • Vous pouvez appliquer l’attribut thread uniquement aux définitions et aux déclarations et déclarations de données de classe ; thread ne peut pas être utilisé sur les déclarations de fonction ou les définitions.

  • Vous pouvez spécifier l’attribut thread uniquement sur les éléments de données avec une durée de stockage statique. Cela inclut des objets de données globaux (à la fois static et extern), des objets statiques locaux et des membres de données statiques de classes. Vous ne pouvez pas déclarer d’objets de données automatiques avec 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 distincts.

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

  • Étant donné que la déclaration d’objets qui utilisent l’attribut thread est autorisée, ces deux exemples sont sémantiquement équivalents :

    // 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.
    
  • La norme C autorise l’initialisation d’un objet ou d’une variable avec une expression impliquant une référence à elle-même, mais uniquement pour les objets non statiques. Bien que C++ autorise normalement une telle initialisation dynamique d’un objet avec une expression impliquant une référence à elle-même, ce type d’initialisation n’est pas autorisé avec des 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 sizeof expression qui inclut l’objet initialisé ne constitue pas une référence à elle-même et est autorisée en C et C++.

FIN de la section spécifique à Microsoft

Voir aussi

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