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:
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.
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 alsextern
auchstatic
), lokale statische Objekte und statische Datenelemente von Klassen. Sie können keine automatischen Datenobjekte mit demthread
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
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für