thread

Sezione specifica Microsoft

Il thread modificatore della classe di archiviazione estesa viene usato per dichiarare una variabile locale del thread. Per l'equivalente portabile in C++11 e versioni successive, usare l'identificatore di classe di archiviazione thread_local per il codice portabile. In Windows thread_local viene implementato con __declspec(thread).

Sintassi

__declspec(thread)declarator

Osservazioni:

L'archiviazione thread-local (TLS, Thread Local Storage) rappresenta il meccanismo mediante il quale ogni processo multithread alloca lo spazio di archiviazione per i dati specifici del thread. Nei programmi multithread standard, i dati vengono condivisi da tutti i thread di un determinato processo, mentre l'archiviazione thread-local è il meccanismo che consente di allocare i dati per singoli thread. Per una descrizione completa dei thread, vedere Multithreading.

Le dichiarazioni delle variabili locali del thread devono usare la sintassi degli attributi estesi e la __declspec parola chiave con la thread parola chiave . Nel codice seguente, ad esempio, viene dichiarata una variabile locale di thread di tipo integer e quindi inizializzata con un valore:

__declspec( thread ) int tls_i = 1;

Quando si usano variabili thread-local nelle librerie caricate in modo dinamico, è necessario essere consapevoli dei fattori che possono causare l'inizializzazione corretta di una variabile locale del thread:

  1. Se la variabile viene inizializzata con una chiamata di funzione (inclusi i costruttori), questa funzione verrà chiamata solo per il thread che ha causato il caricamento del file binario/DLL nel processo e per i thread avviati dopo il caricamento della DLL/binaria. Le funzioni di inizializzazione non vengono chiamate per altri thread già in esecuzione quando la DLL è stata caricata. L'inizializzazione dinamica si verifica nella chiamata dllMain per DLL_THREAD_ATTACH, ma la DLL non riceve mai il messaggio se la DLL non è nel processo all'avvio del thread.

  2. Le variabili locali del thread inizializzate in modo statico con valori costanti vengono in genere inizializzate correttamente in tutti i thread. Tuttavia, a partire da dicembre 2017 si verifica un problema di conformità noto nel compilatore Microsoft C++ in cui constexpr le variabili ricevono variabili dinamiche anziché inizializzazione statica.

    Nota: entrambi questi problemi dovrebbero essere risolti negli aggiornamenti futuri del compilatore.

Inoltre, è necessario osservare queste linee guida quando si dichiarano gli oggetti e le variabili locali del thread:

  • È possibile applicare l'attributo thread solo alle dichiarazioni di classe e ai dati e alle definizioni. thread Non è possibile usare nelle dichiarazioni o nelle definizioni di funzione.

  • È possibile specificare l'attributo thread solo per gli elementi di dati con durata di archiviazione statica. Sono inclusi gli oggetti dati globali (e staticextern), gli oggetti statici locali e i membri dati statici delle classi. Non è possibile dichiarare oggetti dati automatici con l'attributo thread .

  • È necessario usare l'attributo thread per la dichiarazione e la definizione di un oggetto locale del thread, indipendentemente dal fatto che la dichiarazione e la definizione si verifichino nello stesso file o file separati.

  • Non è possibile usare l'attributo thread come modificatore di tipo.

  • Poiché la dichiarazione di oggetti che usano l'attributo thread è consentita, questi due esempi sono semanticamente equivalenti:

    // 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.
    
  • Lo standard C consente l'inizializzazione di un oggetto o di una variabile con un'espressione che include un riferimento a se stesso, ma solo per gli oggetti non statiche. Anche se in genere C++ consente l'inizializzazione dinamica di un oggetto con un'espressione che include un riferimento a se stesso, questo tipo di inizializzazione non è consentito con gli oggetti locali del thread. Ad esempio:

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

    Un'espressione sizeof che include l'oggetto da inizializzare non costituisce un riferimento a se stesso ed è consentita in C e C++.

Fine sezione specifica Microsoft

Vedi anche

__declspec
Parole chiave
Archiviazione thread-local (TLS)