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:
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.
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
eextern
), objetos estáticos locais e membros de dados estáticos de classes. Não é possível declarar objetos de dados automáticos com o atributothread
.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)
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de