Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Microsoft-spezifisch
Der erweiterte Speicherklassenmodifizierer thread
wird verwendet, um eine threadlokale Variable zu deklarieren. Verwenden Sie für das portierbare Äquivalent in C++11 und höher den Speicherklassenbezeichner thread_local für portierbaren Code. Unter Windows wird thread_local
mit __declspec(thread)
implementiert.
Syntax
__declspec(thread)
-Deklarator
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 detaillierte Erläuterung zu Threads finden Sie unter Multithreading.
Deklarationen von threadlokalen Variablen müssen eine erweiterte Attributsyntax und das Schlüsselwort __declspec
mit dem Schlüsselwort thread
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 die Aspekte bewusst machen, die dazu führen können, dass eine threadlokale Variable nicht ordnungsgemäß initialisiert wird:
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-Datei in den Prozess geladen wurde, sowie für die Threads, die nach dem Laden der Binär-/DLL-Datei gestartet wurden. Die Initialisierungsfunktionen werden nicht für einen anderen Thread aufgerufen, der beim Laden der DLL-Datei bereits ausgeführt wurde. Eine dynamische Initialisierung erfolgt im DllMain-Aufruf für DLL_THREAD_ATTACH. Die DLL-Datei erhält diese Nachricht aber nie, wenn die DLL-Datei nicht verarbeitet, wenn der Thread gestartet wird.
Threadlokale Variablen, die statisch mit konstanten Werten initialisiert wurden, werden im Allgemeinen in allen Threads ordnungsgemäß initialisiert. Seit Dezember 2017 gibt es jedoch ein bekanntes Konformitätsproblem im Microsoft C++-Compiler, durch das für
constexpr
-Variablen eine dynamische anstelle einer statischen Initialisierung erfolgt.Hinweis: Beide Probleme werden voraussichtlich mit zukünftigen Updates des Compilers behoben.
Sie müssen diese Richtlinien auch beachten, wenn Sie threadlokale Objekte 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. Hierzu zählen globale Datenobjekte (sowohlstatic
als auchextern
), lokale statische Objekte sowie statische Datenmember von Klassen. Sie können mit demthread
-Attribut keine automatischen Datenobjekte deklarieren.Sie müssen das
thread
-Attribut für die Deklaration und Definition eines threadlokalen Objekts verwenden, unabhängig davon, ob die Deklaration und Definition in der gleichen Datei oder in separaten Dateien erfolgen.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.
In Standard-C ist die Initialisierung eines Objekts oder einer Variable mit einem Ausdruck zulässig, der einen Verweis auf sich selbst enthält. Dies gilt jedoch nur für nicht statische Objekte. Auch wenn diese dynamische Objektinitialisierung mit einem Ausdruck, der einen Verweis auf sich selbst enthält, in C++ normalerweise als zulässig gilt, ist dieser Initialisierungstyp für threadlokale Objekte nicht zulässig. Zum 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 Objekt enthält, das derzeit initialisiert wird, stellt keinen Verweis auf sich selbst dar und ist sowohl in C als auch in C++ zulässig.
Ende Microsoft-spezifisch