Gibt es einen Unterschied zwischen diesen beiden Codesegmenten:
void f() {
thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}
und
void f() {
static thread_local vector<int> V;
V.clear();
... // use V as a temporary variable
}
Hintergrundgeschichte: Ursprünglich hatte ich einen STATISCHEN Vektor V (zum Halten einiger Zwischenwerte wird er bei jeder Eingabe der Funktion gelöscht) und ein Single-Thread-Programm. Ich möchte das Programm in ein Multithreading-Programm verwandeln, also muss ich diesen statischen Modifikator irgendwie loswerden. Meine Idee ist es, jede Statik in thread_local umzuwandeln und sich um nichts anderes zu kümmern? Kann dieser Ansatz nach hinten losgehen?
thread_local
lokale Variable zu haben macht zunächst keinen Sinn ... jeder Thread hat seinen eigenen Aufrufstapel.static
anstattstatic thread_local
nicht eine Instanz der Variablen für jeden Thread zu initialisieren.static
vsstatic thread_local
, sondern vonauto
vsthread_local
, wobei die Bedeutung vonauto
(dh automatischer Speicher) vor C ++ 11 verwendet wird.Antworten:
Nach dem C ++ Standard
Das bedeutet also, dass diese Definition
ist äquivalent zu
Eine statische Variable ist jedoch nicht mit einer thread_local-Variablen identisch.
Zur Unterscheidung dieser Variablen führt der Standard einen neuen Begriff Thread-Speicherdauer zusammen mit statischer Speicherdauer ein.
quelle
static
undextern
implizieren daher keine Speicherklasse, sondern nur eine Verknüpfung für thread_local-Variablen, selbst in inneren Bereichen.Ja, "threadlokaler Speicher" ist "global" (oder "statischer Speicher") sehr ähnlich, nur dass anstelle von "Dauer des gesamten Programms" "Dauer des gesamten Threads" angezeigt wird. Daher wird eine blocklokale threadlokale Variable beim ersten Durchlauf der Steuerung durch ihre Deklaration initialisiert, jedoch separat in jedem Thread, und sie wird zerstört, wenn der Thread endet.
quelle
Bei Verwendung mit
thread_local
,static
wird angedeutet , in Block-Rahmen (siehe @ Vlad Antwort), für eine Klasse Mitglied requied; Ich denke, bedeutet Verknüpfung für Namespace-Bereich.Per 9.2 / 6:
So beantworten Sie die ursprüngliche Frage:
Es gibt keine andere Wahl als Namespace-Scope-Variablen.
Nein.
quelle
Der lokale Thread-Speicher ist statisch, verhält sich jedoch ganz anders als der einfache statische Speicher.
Wenn Sie eine Variable als statisch deklarieren, gibt es genau eine Instanz der Variablen. Das Compiler- / Laufzeitsystem garantiert, dass es irgendwann vor der tatsächlichen Verwendung für Sie initialisiert wird, ohne genau anzugeben, wann (einige Details wurden hier weggelassen).
C ++ 11 garantiert, dass diese Initialisierung threadsicher ist. Vor C ++ 11 wurde diese Thread-Sicherheit jedoch nicht garantiert. Beispielsweise
Es können Instanzen von X verloren gehen, wenn mehr als ein Thread gleichzeitig den statischen Initialisierungscode trifft.
Wenn Sie einen Variablenthread lokal deklarieren, gibt es möglicherweise viele Instanzen der Variablen. Sie können sich diese als eine Karte vorstellen, die durch die Thread-ID indiziert wurde. Das bedeutet, dass jeder Thread eine eigene Kopie der Variablen sieht.
Wenn die Variable initialisiert wird, garantiert das Compiler- / Laufzeitsystem erneut, dass diese Initialisierung vor der Verwendung der Daten erfolgt und dass die Initialisierung für jeden Thread erfolgt, der die Variable verwendet. Der Compiler garantiert auch, dass die Initiierung threadsicher ist.
Die Thread-Sicherheitsgarantie bedeutet, dass es hinter den Kulissen eine Menge Code geben kann, damit sich die Variable so verhält, wie Sie es erwarten - insbesondere, wenn man bedenkt, dass der Compiler nicht im Voraus genau wissen kann, wie viele Threads dies tun werden sind in Ihrem Programm vorhanden und wie viele davon berühren die lokale Thread-Variable.
quelle