thread

Seção específica da Microsoft

O modificador de classe de armazenamento estendido thread é usado para declarar uma variável local de thread. Para o equivalente portátil em C++11 e posterior, use o especificador de classe de armazenamento thread_local para código portátil. No Windows, thread_local é implementado com __declspec(thread).

Sintaxe

__declspec(thread)declarator

Comentários

O TLS (armazenamento local de threads) é o mecanismo pelo qual cada thread em um processo multithread aloca armazenamento para dados específicos ao thread. Em programas multithread padrão, os dados são compartilhados entre todos os threads de um processo específico, enquanto o armazenamento local de threads é o mecanismo para alocar dados por thread. Para ver uma discussão completa de threads, confira Multithreading.

As declarações de variáveis locais de thread devem usar sintaxe de atributo estendido e a palavra-chave __declspec com a palavra-chave thread. Por exemplo, o código a seguir declara uma variável local de thread de inteiro e a inicializa com um valor:

__declspec( thread ) int tls_i = 1;

Ao usar variáveis locais de thread em bibliotecas carregadas dinamicamente, você precisa estar ciente dos fatores que podem fazer com que uma variável local de thread não seja inicializada corretamente:

  1. Se a variável for inicializada com uma chamada de função (incluindo construtores), essa função só será chamada para o thread que carregou o binário/DLL no processo e para os threads iniciados depois que o binário/DLL foi carregado. As funções de inicialização não são chamadas para nenhum outro thread que já estava em execução quando a DLL foi carregada. A inicialização dinâmica ocorre na chamada DllMain para DLL_THREAD_ATTACH, mas a DLL nunca receberá essa mensagem se ela não estiver no processo quando o thread for iniciado.

  2. Variáveis locais de thread que são inicializadas estaticamente com valores constantes são geralmente inicializadas corretamente em todos os threads. No entanto, a partir de dezembro de 2017, há um problema de conformidade conhecido no compilador C++ da Microsoft em que as variáveis constexpr recebem inicialização dinâmica em vez de estática.

    Observação: espera-se que ambos os problemas sejam corrigidos em atualizações futuras do compilador.

É necessário observar estas diretrizes ao declarar objetos e variáveis locais de thread:

  • Somente é possível aplicar o atributo thread às declarações e definições de dados, e às classes que não têm funções de membro; thread não pode ser usado em declarações ou definições de função.

  • Você pode especificar o atributo thread apenas em itens de dados com duração de armazenamento estático. Isso inclui objetos de dados globais (static e extern), objetos estáticos locais e membros de dados estáticos de classes. Não é possível declarar objetos de dados automáticos com o atributo thread.

  • Você deve usar o atributo thread para a declaração e a definição de um objeto local de thread, independentemente se a declaração e a definição ocorram no mesmo arquivo ou em arquivos separados.

  • Não é possível usar o atributo thread como um modificador de tipo.

  • Como a declaração de objetos que usam o atributo thread é permitida, estes dois exemplos são semanticamente equivalentes:

    // 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.
    
  • C padrão permite a inicialização de um objeto ou uma variável com uma expressão que envolva uma referência a si mesma, mas apenas para objetos não estáticos. Embora o C++ normalmente permita essa inicialização dinâmica de um objeto com uma expressão envolvendo uma referência a si mesma, esse tipo de inicialização não é permitido com objetos locais de thread. Por exemplo:

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

    Uma expressão sizeof que inclui o objeto que está sendo inicializado não constitui uma referência a si mesma e é permitida em C e C++.

Fim da seção específica da Microsoft

Confira também

__declspec
Palavras-chave
TLS (armazenamento local de thread)