thread

Microsoft-spezifisch

Der thread erweiterte Speicherklassenmodifizierer wird verwendet, um eine lokale Threadvariable zu deklarieren. Verwenden Sie für das portierbare Äquivalent in C++11 und höher den thread_local Speicherklassenbezeichner für tragbaren Code. Unter Windows thread_local wird mit __declspec(thread).

Syntax

__declspec(thread)declarator

Hinweise

Threadlokaler Speicher (TLS) ist der Mechanismus, mit dem jeder Thread in einem Multithreadprozess den Speicher für threadspezifische Daten zuordnet. In den standardmäßigen Multithreadprogrammen werden Daten auf allen Threads eines angegebenen Prozesses freigegeben, während der threadlokale Speicher der Mechanismus zum Zuordnen der threadspezifischen Daten ist. Eine vollständige Erläuterung von Threads finden Sie unter Multithreading.

Deklarationen lokaler Threadvariablen müssen eine erweiterte Attributsyntax und die __declspec Schlüsselwort (keyword) mit dem thread Schlüsselwort (keyword) verwenden. Mit folgendem Code wird z. B. eine Ganzzahl-TLS-Variable deklariert und mit einem Wert initialisiert:

__declspec( thread ) int tls_i = 1;

Wenn Sie threadlokale Variablen in dynamisch geladenen Bibliotheken verwenden, müssen Sie sich über Faktoren bewusst sein, die dazu führen können, dass eine threadlokale Variable nicht ordnungsgemäß initialisiert wird:

  1. Wenn die Variable mit einem Funktionsaufruf (einschließlich Konstruktoren) initialisiert wird, wird diese Funktion nur für den Thread aufgerufen, der dazu führte, dass die Binär-/DLL in den Prozess geladen wurde, und für diese Threads, die nach dem Laden der Binär-/DLL gestartet wurden. Die Initialisierungsfunktionen werden nicht für einen anderen Thread aufgerufen, der beim Laden der DLL bereits ausgeführt wurde. Dynamische Initialisierung erfolgt im DllMain-Aufruf für DLL_THREAD_ATTACH, aber die DLL erhält diese Nachricht nie, wenn die DLL nicht im Prozess ist, wenn der Thread gestartet wird.

  2. Threadlokale Variablen, die statisch mit Konstantenwerten initialisiert werden, werden in allen Threads im Allgemeinen ordnungsgemäß initialisiert. Ab Dezember 2017 gibt es jedoch ein bekanntes Konformitätsproblem im Microsoft C++-Compiler, bei dem constexpr Variablen dynamische statt statische Initialisierung erhalten.

    Hinweis: Beide Probleme werden voraussichtlich in zukünftigen Updates des Compilers behoben.

Darüber hinaus müssen Sie diese Richtlinien beachten, wenn Sie lokale Threadobjekte und Variablen deklarieren:

  • Sie können das thread Attribut nur auf Klassen- und Datendeklarationen und Definitionen anwenden; thread kann nicht für Funktionsdeklarationen oder Definitionen verwendet werden.

  • Sie können das thread Attribut nur für Datenelemente mit statischer Speicherdauer angeben. Dazu gehören globale Datenobjekte (sowohl als externauch static ), lokale statische Objekte und statische Datenelemente von Klassen. Sie können keine automatischen Datenobjekte mit dem thread Attribut deklarieren.

  • Sie müssen das thread Attribut für die Deklaration und die Definition eines lokalen Threadobjekts verwenden, unabhängig davon, ob die Deklaration und Definition in derselben Datei oder separaten Dateien auftreten.

  • Sie können das thread Attribut nicht als Typmodifizierer verwenden.

  • Da die Deklaration von Objekten, die das thread Attribut verwenden, zulässig ist, sind diese beiden Beispiele semantisch gleichwertig:

    // 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.
    
  • Standard C ermöglicht die Initialisierung eines Objekts oder einer Variablen mit einem Ausdruck, der einen Verweis auf sich selbst umfasst, jedoch nur für nicht statische Objekte. Obwohl C++ normalerweise eine solche dynamische Initialisierung eines Objekts mit einem Ausdruck zulässt, der einen Verweis auf sich selbst umfasst, ist diese Art der Initialisierung mit threadlokalen Objekten nicht zulässig. Beispiel:

    // 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++
    

    Ein sizeof Ausdruck, der das initialisierte Objekt enthält, stellt keinen Verweis auf sich selbst dar und ist in C und C++ zulässig.

Ende Microsoft-spezifisch

Siehe auch

__declspec
Schlüsselwörter
Threadlokaler Speicher (TLS)