vlákno

Specifické pro Microsoft

Modifikátor thread rozšířené třídy úložiště slouží k deklaraci místní proměnné vlákna. Pro přenositelný ekvivalent v jazyce C++11 a novější použijte specifikátor třídy úložiště thread_local pro přenositelný kód. Ve Windows thread_local se implementuje s __declspec(thread).

Syntaxe

__declspec(thread)deklarátor deklarátor

Poznámky

Místní úložiště vláken (TLS) je mechanismus, podle kterého všechna vlákna procesu alokují prostor pro data určitého vlákna. U standardních aplikací s více vlákny jsou data sdílena mezi všemi vlákny daného procesu, kde místní úložiště vláken představuje mechanismus pro rozdělení dat pro vlákno. Úplnou diskuzi o vláknech najdete v tématu Multithreading.

Deklarace místních proměnných vlákna musí používat rozšířenou syntaxi atributů a __declspec klíčové slovo s klíčovým slovem thread . Například následující kód deklaruje místní proměnnou celočíselného vlákna a inicializuje ji hodnotou:

__declspec( thread ) int tls_i = 1;

Při použití lokálních proměnných vláken v dynamicky načtených knihovnách je potřeba vědět o faktorech, které mohou způsobit, že místní proměnná vlákna nebude inicializována správně:

  1. Pokud je proměnná inicializována voláním funkce (včetně konstruktorů), bude tato funkce volána pouze pro vlákno, které způsobilo načtení binárního souboru nebo knihovny DLL do procesu, a pro vlákna, která se spustila po načtení binární knihovny nebo knihovny DLL. Inicializační funkce nejsou volána pro žádné jiné vlákno, které již bylo spuštěno při načtení knihovny DLL. Dynamická inicializace probíhá při volání DllMain pro DLL_THREAD_ATTACH, ale knihovna DLL tuto zprávu nikdy nedostane, pokud knihovna DLL není v procesu při spuštění vlákna.

  2. Místní proměnné vlákna, které jsou inicializovány staticky s konstantními hodnotami, jsou obecně správně inicializovány ve všech vláknech. Od prosince 2017 však existuje známý problém s shodami v kompilátoru Jazyka C++, kdy constexpr proměnné přijímají dynamické místo statické inicializace.

    Poznámka: V budoucích aktualizacích kompilátoru se očekává, že oba tyto problémy budou opraveny.

Kromě toho musíte při deklarování místních objektů a proměnných vlákna dodržovat tyto pokyny:

  • Atribut můžete použít thread pouze u deklarací tříd a dat a definic. thread Nelze použít u deklarací nebo definic funkcí.

  • Atribut můžete zadat thread pouze u datových položek s dobou trvání statického úložiště. To zahrnuje globální datové objekty (i staticextern), místní statické objekty a statické datové členy tříd. Pomocí atributu thread nelze deklarovat automatické datové objekty.

  • Musíte použít thread atribut pro deklaraci a definici místního objektu vlákna, ať už deklarace a definice probíhají ve stejném souboru nebo v samostatných souborech.

  • Atribut nelze použít thread jako modifikátor typu.

  • Vzhledem k tomu, že deklarace objektů, které používají thread atribut, je povolena, jsou tyto dva příklady sémanticky ekvivalentní:

    // 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.
    
  • Standardní jazyk C umožňuje inicializaci objektu nebo proměnné pomocí výrazu zahrnujícího odkaz na sebe sama, ale pouze pro nestatické objekty. I když C++ obvykle umožňuje takovou dynamickou inicializaci objektu s výrazem zahrnujícím odkaz na sebe, tento typ inicializace není povolen s místními objekty vlákna. Příklad:

    // 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++
    

    Výraz sizeof , který obsahuje inicializovaný objekt, nepředstavuje odkaz na sebe a je povolen v jazyce C a C++.

END Microsoft Specific

Viz také

__declspec
Klíčová slova
Úložiště Thread Local (TLS)