Was bedeutet die thread_local bedeuten in C++11?
Ich bin verwirrt mit der Beschreibung von thread_local
in C++11. Mein Verständnis ist, jeder thread hat einzigartige Kopie der lokalen Variablen in einer Funktion. Die globalen/statischen Variablen zugegriffen werden kann von allen threads (evtl. synchronisierten Zugriff mit einem Schloss). Und die thread_local
Variablen sind für alle sichtbar, die Fäden können aber nur geändert durch das Gewinde, für die Sie definiert sind? Ist es richtig?
InformationsquelleAutor polapts | 2012-08-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Thread-local-storage-Dauer ist ein Begriff verwendet, um auf Daten verweisen, die scheinbar Globale oder statische Speicher Dauer (aus Sicht der Funktionen, die mit es), aber in der Tat, es ist eine Kopie pro thread.
Fügt es dem aktuellen automatischen (ist während eines Blocks/der Funktion), statisch (besteht für die Dauer des Programms) und dynamische (existiert auf dem heap zwischen Reservierung und Freigabe).
Etwas, das ist thread-lokal ist) brachte in Existenz bei der thread-Erstellung und entsorgt, wenn der thread beendet.
Einige Beispiele Folgen.
Denken Sie an einen Zufallszahlen-generator, wo die Saat muss gepflegt werden, auf einer pro-thread-basis. Mit einer thread-lokalen Saatgut-bedeutet, dass jeder thread erhält eine eigene random number sequence, unabhängig von anderen threads.
Wenn Ihr Samen wurde eine lokale variable innerhalb der random-Funktion, es würde initialisiert werden jedes mal, wenn Sie ihn genannt haben, geben Sie die gleiche Anzahl jedes mal. Wenn es zu einem globalen, threads stören würde, mit den jeweils anderen Sequenzen.
Weiteres Beispiel ist so etwas wie
strtok
wo der tokenisation Zustand gespeichert ist, in einem thread-spezifischen basis. So ein einzelner thread kann sicher sein, dass andere threads nicht versauen seine tokenisation Bemühungen, während noch in der Lage zu halten Zustand über mehrere Aufrufe zustrtok
- diese im Grunde machtstrtok_r
(der thread-safe version) überflüssig.Diese beiden Beispiele ermöglichen die thread-lokale variable existiert innerhalb die Funktion, die verwendet wird. In der pre-threaded-code, wäre es einfach eine statische Speicher Dauer variable innerhalb der Funktion. Für threads, die geändert wird, um die thread-lokalen Speicher-Dauer.
Weiteres Beispiel wäre so etwas wie
errno
. Sie wollen nicht separate threads ändernerrno
nach einem von Ihr fordert, schlägt aber vor, können Sie prüfen, die Variablen, und doch ist Sie nur eine Kopie pro thread.Diese Website hat eine angemessene Beschreibung der verschiedenen Speicher-Dauer-Bezeichner.
strtok
Vorschlag!Mit thread-lokalen nicht die Probleme lösen, die mit
strtok
.strtok
gebrochen ist auch in einer single-threaded Umgebung.Sorry, lassen Sie mich das anders formulieren. Es nicht einführen, neuen Probleme mit strtok 🙂
Tatsächlich, die
r
steht für "re-entrant", das hat nichts zu tun mit der thread-Sicherheit. Es ist wahr, dass Sie können einige Dinge, die Arbeit, die thread-sicher mit thread-lokalen Speicher, aber Sie können diese nicht re-entrant ist.In einem single-threaded-Umgebung, Funktionen, müssen neu-Teilnehmer nur, wenn Sie Teil eines Zyklus im aufrufgraph. Ein Blatt-Funktion (eine, die nicht andere Funktionen aufrufen) ist per definition nicht Teil eines Zyklus, und es gibt keinen guten Grund, warum
strtok
sollten andere Funktionen aufrufen.InformationsquelleAutor paxdiablo
Wenn Sie eine variable deklarieren
thread_local
dann jeder thread verfügt über seine eigene Kopie. Wenn Sie finden es durch den Namen, dann die Kopie dem aktuellen thread zugeordnet ist, verwendet. z.B.Dieser code ausgegeben wird "2349", "3249", "4239", "4329", "2439" oder "3429", aber nie etwas anderes. Jeder thread verfügt über seine eigene Kopie des
i
, die zugeordnet ist, inkrementiert und anschließend ausgedruckt werden. Der thread läuftmain
hat auch seine eigene Kopie, die zugewiesen wird, um am Anfang und dann unverändert gelassen. Diese Kopien sind völlig unabhängig, und jeder hat eine andere Adresse.Es ist nur die Namen, dass ist das Besondere in dieser Hinsicht --- wenn Sie die Adresse eines
thread_local
variable, dann haben Sie nur einen normalen Zeiger auf ein normales Objekt, das Sie können ungehindert zwischen den threads. z.B.Da die Adresse von
i
wird an die thread-Funktion, dann die Kopie deri
Zugehörigkeit zu den Haupt-thread zugeordnet werden kann, obwohl esthread_local
. Dieses Programm wird daher die Ausgabe "42". Wenn Sie dies tun, dann müssen Sie aufpassen, dass*p
wird nicht zugegriffen, nachdem der thread gehört es zu verlassen hat, sonst erhalten Sie einen baumelnden Zeiger und Undefiniertes Verhalten genau wie jeder andere Fall, wo die Spitzen-zu-Objekt zerstört wird.thread_local
Variablen werden initialisiert "vor dem ersten Gebrauch", so, wenn Sie nie berührt, die von einem bestimmten thread, dann sind Sie nicht unbedingt immer initialisiert. Dieser ist es, den Compilern zu vermeiden konstruieren jedethread_local
variable im Programm für ein thread, ist vollständig eigenständig und nicht berühren. z.B.In diesem Programm gibt es 2 threads: der main-thread und der manuell erstellten thread. Weder thread-Aufrufe
f
, so diethread_local
Objekt nie verwendet. Es ist daher nicht spezifiziert, ob der compiler konstruieren, die 0, 1 oder 2 Instanzen vonmy_class
, und die Ausgabe "", "hellohellogoodbyegoodbye" oder "hellogoodbye".g()
Aufruf der AnfangthreadFunc
, dann wird die Ausgabe0304029
oder eine andere permutation der Paare02
,03
, und04
. Das ist, obwohl 9 zugeordnet isti
bevor die threads sind erstellt, die threads bekommen eine frisch konstruierte Kopie voni
woi=0
. Wenni
zugeordnet ist, mitthread_local int i = random_integer()
dann jeder thread bekommt eine neue zufällige Ganzzahl.Nicht genau eine permutation
02
,03
,04
, es können auch andere Sequenzen wie020043
InformationsquelleAutor Anthony Williams
Thread-local storage ist in jeder Hinsicht wie statische (= globalen) Speicher, nur, dass jeder thread verfügt über eine separate Kopie des Objekts. Das Objekt ist Leben Zeit beginnt entweder am thread start (für Globale Variablen) oder auf den ersten Initialisierung (block-lokalen Statik), und endet, wenn der thread beendet wird (D. H. wenn
join()
genannt wird).Somit nur Variablen, die könnte auch erklärt werden
static
erklärt werden können alsthread_local
, d.h. Globale Variablen (genauer: Variablen "im namespace-Gültigkeitsbereich"), statische Klassenmitglieder, und block-statische Variablen (in dem Fallstatic
impliziert ist).Als ein Beispiel angenommen, Sie haben einen thread-pool und möchten wissen, wie gut Sie Ihre Arbeit Last war ausgeglichen:
Diese drucken würde thread Nutzungsstatistiken, z.B. mit einer Umsetzung wie diese:
InformationsquelleAutor Kerrek SB