Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
TLS (Thread Local Storage) är den metod med vilken varje tråd i en viss process med flera trådar kan allokera platser där trådspecifika data ska lagras. Trådspecifika data som är dynamiskt bundna (körningstid) stöds via TLS API (TlsAlloc). Win32 och Microsoft C++-kompilatorn stöder nu statiskt bundna data (belastningstid) per tråd utöver den befintliga API-implementeringen.
Implementering av kompilator för TLS
C++11: Lagringsklassspecificeraren thread_local är det rekommenderade sättet att ange trådlokal lagring för objekt och klassmedlemmar. Mer information finns i Lagringsklasser (C++).
MSVC tillhandahåller också ett Microsoft-specifikt attribut, tråd, som utökad lagringsklassmodifierare. Använd nyckelordet __declspec för att deklarera en thread variabel. Följande kod deklarerar till exempel en lokal heltalstrådsvariabel och initierar den med ett värde:
__declspec( thread ) int tls_i = 1;
Regler och begränsningar
Följande riktlinjer måste följas när statiskt bundna trådlokala objekt och variabler deklareras. Dessa riktlinjer gäller både för tråd och för thread_local:
Attributet
threadkan endast tillämpas på klass- och datadeklarationer och definitioner. Det kan inte användas i funktionsdeklarationer eller definitioner. Följande kod genererar till exempel ett kompilatorfel:__declspec( thread )void func(); // This will generate an error.Modifieraren
threadkan endast anges för dataobjekt istaticviss utsträckning. Det inkluderar globala dataobjekt (bådestaticochextern), lokala statiska objekt och statiska datamedlemmar i C++-klasser. Automatiska dataobjekt kan inte deklareras med attributetthread. Följande kod genererar kompilatorfel:void func1() { __declspec( thread )int tls_i; // This will generate an error. } int func2(__declspec( thread )int tls_i ) // This will generate an error. { return tls_i; }Deklarationerna och definitionen av ett lokalt trådobjekt måste alla ange attributet
thread. Följande kod genererar till exempel ett fel:#define Thread __declspec( thread ) extern int tls_i; // This will generate an error, since the int __declspec( thread )tls_i; // declaration and definition differ.Attributet
threadkan inte användas som typmodifierare. Följande kod genererar till exempel ett kompilatorfel:char __declspec( thread ) *ch; // ErrorEftersom deklarationen av C++-objekt som använder
threadattributet tillåts är följande två exempel semantiskt likvärdiga:__declspec( thread ) class B { // Code } BObject; // OK--BObject is declared thread local. class B { // Code }; __declspec( thread ) B BObject; // OK--BObject is declared thread local.Adressen till ett lokalt trådobjekt betraktas inte som konstant och alla uttryck som involverar en sådan adress betraktas inte som ett konstant uttryck. I standard C är effekten att inte tillåta att adressen för en trådlokal variabel används som initiator för ett objekt eller en pekare. Följande kod flaggas till exempel som ett fel av C-kompilatorn:
__declspec( thread ) int tls_i; int *p = &tls_i; //This will generate an error in C.Den här begränsningen gäller inte i C++. Eftersom C++ möjliggör dynamisk initiering av alla objekt kan du initiera ett objekt med hjälp av ett uttryck som använder adressen för en trådlokal variabel. Det görs precis som skapandet av trådlokala objekt. Koden som visades tidigare genererar till exempel inget fel när den kompileras som en C++-källfil. Adressen för en lokal trådvariabel är endast giltig så länge tråden där adressen togs fortfarande finns.
Standard C möjliggör initiering av ett objekt eller en variabel med ett uttryck som omfattar en referens till sig själv, men endast för objekt av icke-statisk omfattning. Även om C++ i allmänhet tillåter sådan dynamisk initiering av objekt med ett uttryck som innehåller en referens till sig själv, tillåts inte den här typen av initiering med trådlokala objekt. Till exempel:
__declspec( thread )int tls_i = tls_i; // Error in C and C++ int j = j; // OK in C++, error in C __declspec( thread )int tls_i = sizeof( tls_i ) // Legal in C and C++Ett
sizeofuttryck som innehåller objektet som initieras representerar inte en referens till sig själv och är aktiverat i både C och C++.C++ tillåter inte sådan dynamisk initiering av tråddata på grund av eventuella framtida förbättringar av den lokala trådlagringsanläggningen.
På Windows-operativsystem före Windows Vista
__declspec( thread )har vissa begränsningar. Om en DLL deklarerar data eller objekt som__declspec( thread )kan det orsaka ett skyddsfel om de läses in dynamiskt. När DLL:en har lästs in med LoadLibrary orsakar den systemfel när koden refererar till__declspec( thread )data. Eftersom det globala variabelutrymmet för en tråd allokeras vid körning baseras storleken på det här utrymmet på en beräkning av programmets krav plus kraven för alla DLL:er som är statiskt länkade. När du använderLoadLibrarykan du inte utöka det här utrymmet för att tillåta de lokala trådvariabler som deklarerats med__declspec( thread ). Använd TLS-API:erna, till exempel TlsAlloc, i din DLL för att allokera TLS om DLL-filen kan läsas in medLoadLibrary.