2010-09-17 12 views
10

Wie implementiert C++ Compiler Thread lokalen Speicher in C++ 0 xWie implementiert ein C++ - Compiler lokalen Threadspeicher in C++ 0x?

Ich habe dies in Google gesucht. Aber ich kann nichts darüber finden.

Hat jemand Material dazu?

+0

Der C++ - Standard hat keine (oder sehr wenige) Implementierungsdetails. –

+0

Dies kann jetzt helfen: http://www.akkadia.org/drepper/tls.pdf –

Antwort

13

Lesen Sie die Wikipedia entry.

Thread-lokaler Speicher ist nicht speziell für C++. Manchmal wird es unter verschiedenen Namen wie "TLS" (nur eine Abkürzung von thread-local Speicher) oder "Thread-spezifische Speicher" (TSS).

Die meisten Betriebssysteme stellen APIs für den Zugriff auf den Threadspeicher bereit. Zum Beispiel hat Windows eine bunch of API functions beginnend mit "TLS". Unter der Haube reserviert Win32 einen speziellen Bereich für eine Vielzahl von pro-Thread-Daten, einschließlich Benutzer Thread-lokalen Speicher, zugänglich durch ein bestimmtes CPU-Register (FS auf x86). Linux bietet Thread-spezifischen Speicher über die Pthread-APIs mit Namen wie pthread_key_create, und diese werden im Allgemeinen mit einer ähnlichen Technik implementiert.

Es ist möglich, dass ein Betriebssystem überhaupt keine Unterstützung bietet. Wenn das Betriebssystem jedoch über eine API eine prozessspezifische Thread-ID bereitstellt, könnte die C++ - Laufzeitbibliothek intern etwas konzeptionell wie std::map<thread_id, per_thread_storage> verwalten. Natürlich gibt es ein Problem, was per_thread_storage ist. Wenn ein Programm statisch verknüpft ist, könnte es einfach so etwas wie ein Zeiger auf eine große Struktur mit allen Thread-lokalen Speichervariablen sein, die im Programm als Elemente deklariert sind. Dies ist eine zu starke Vereinfachung, aber Sie erhalten die allgemeine Idee.

Der Zugriff auf Thread-lokale Speichervariablen ist offensichtlich nicht nur ein direkter Lese- oder Schreibzugriff. Es ist möglicherweise ein bisschen mehr beteiligt als das. Wenn Sie in einer bestimmten Funktion häufig threadlokalen/spezifischen Speicher verwenden möchten, empfehle ich Ihnen, zuerst den threadlokalen Speicherzeiger in eine lokale Variable zu kopieren.

+2

Sie haben geantwortet, wie ein Anwendungsentwickler TLS implementieren kann, aber nicht, wie der Compiler und der Lader das C++ 0x thread_local-Schlüsselwort behandeln – doron

+6

@ Doron: Der Compiler und der Loader verwenden entweder die vom Betriebssystem bereitgestellten APIs oder sie machen etwas, das der Abbildungstechnik selbst entspricht, ohne dass der Anwendungsprogrammierer Code schreiben muss. – Doug

4

Globale Variablen (oder schreibbare statische Daten - WSD) werden normalerweise in einem Speicherblock getrennt von Stack, Heap und Code gespeichert. Der WSD-Block wird erstellt und initialisiert, bevor der Code der ausführbaren Datei ausgeführt wird.

C++ 0x führt das Schlüsselwort thread_local ein, das sicherstellt, dass eine separate Instanz der globalen Variablen pro Thread erstellt wird. Das Problem ist, dass ein anderer Block pro Thread geladen werden muss.

Die nächste Schwierigkeit besteht darin, dass die Adresse der Variablen nicht zur Verbindungszeit festgelegt ist und für jeden Thread unterschiedlich ist.

Es gibt zwei Möglichkeiten, dieses Problem zu umgehen. Einer besteht darin, dass der Compiler einen Funktionsaufruf generiert, um den korrekten Block zu erhalten, während der andere den ABI ändert, um den TLS-Block in einem der Prozessorregister zu speichern. Dies kann dann mit Offsets verwendet werden, um auf die korrekte Variable thread_local zuzugreifen.

Dies unterscheidet sich von der Bibliotheksunterstützung, bei der das Betriebssystem einen einzelnen Wert void* speichert, der verwendet werden kann, um einen Zeiger auf einen lokalen Threadblock zu speichern, der auf dem Prozesszwischenspeicher zugeordnet wurde.

Wenn Sie die blutigen Details sehen wollen, schauen Sie here.

0

Sie können boost::thread verwenden, um TLS auf verschiedenen Plattformen portabel zu verarbeiten. Die Implementierung in jedem Fall ist im Code enthalten und sollte Ihnen dabei helfen zu verstehen, wie verschiedene Systeme mit diesem Bereich umgehen.

+1

In C++ 0x unterstützt der Compiler TLS mit dem Schlüsselwort thread_local – doron

+0

Mit Boost ist in Ordnung, aber für den Rekord haben einige Compiler tatsächlich in den Problembereich gekauft. http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html –

+0

Sie haben Recht, ich werde dies aktualisieren. –