Compartilhar via


Regras e limitações de TLS

As diretrizes a seguir devem ser observadas quando declarar estaticamente ligado segmento local objetos e variáveis:

  • O thread atributo pode ser aplicado somente a definições e declarações de dados.Ele não pode ser usado em declarações de função ou definições.Por exemplo, o código a seguir gera um erro do compilador:

    #define Thread  __declspec( thread )
    Thread void func();     // This will generate an error.
    
  • O thread modificador pode ser especificado somente em itens de dados com static extensão.Isso inclui objetos de dados globais (ambos static e extern), locais objetos estáticos e membros de dados estáticos de classes C++.Objetos de dados automáticos não podem ser declarados com o thread atributo.O código a seguir gera erros do compilador:

    #define Thread  __declspec( thread )
    void func1()
    {
        Thread int tls_i;            // This will generate an error.
    }
    
    int func2( Thread int tls_i )    // This will generate an error.
    {
        return tls_i;
    }
    
  • As declarações e a definição de um thread objeto local deve especificar o thread atributo.Por exemplo, o código a seguir gera um erro:

    #define Thread  __declspec( thread )
    extern int tls_i;        // This will generate an error, since the
    int Thread tls_i;        // declaration and definition differ.
    
  • O thread atributo não pode ser usado como um modificador de tipo.Por exemplo, o código a seguir gera um erro do compilador:

    char __declspec( thread ) *ch;        // Error
    
  • Classes C++ não é possível usar o thread atributo.No entanto, os objetos de classe do C++ podem ser instanciados com a thread atributo.Por exemplo, o código a seguir gera um erro do compilador:

    #define Thread  __declspec( thread )
    class Thread C       // Error: classes cannot be declared Thread.
    {
    // Code
    };
    C CObject;
    

    Porque a declaração de C++ objetos que usam o thread atributo é permitido, dois exemplos a seguir são semanticamente equivalentes:

    #define Thread  __declspec( thread )
    Thread class B
    {
    // Code
    } BObject;               // OK--BObject is declared thread local.
    
    class B
    {
    // Code
    };
    Thread B BObject;        // OK--BObject is declared thread local.
    
  • O endereço de um objeto local de thread não é considerado constante e qualquer expressão envolvendo um endereço não é considerada uma expressão de constante.C padrão, o efeito é proibir o uso do endereço de uma variável de segmento local como um inicializador de um objeto ou um ponteiro.Por exemplo, o código a seguir é sinalizado como um erro pelo compilador C:

    #define Thread  __declspec( thread )
    Thread int tls_i;
    int *p = &tls_i;       //This will generate an error in C.
    

    Essa restrição não se aplica em C++.Porque C++ permite inicialização dinâmica de todos os objetos, você pode inicializar um objeto usando uma expressão que utiliza o endereço de uma variável de segmento local.Isso é feito exatamente como a construção de objetos de thread local.Por exemplo, o código mostrado anteriormente não gera um erro quando ele é compilado como um arquivo de origem C++.Observe que o endereço de uma variável de segmento local é válido apenas como o thread no qual o endereço foi tirado ainda existe.

  • C padrão permite a inicialização de um objeto ou variável com uma expressão que envolve uma referência a mesmo, mas somente para objetos de extensão não estático.Embora C++ geralmente permite tal inicialização dinâmica de objetos com uma expressão que envolve uma referência a mesmo, esse tipo de inicialização não é permitido com objetos de thread local.Por exemplo:

    #define Thread  __declspec( thread )
    Thread int tls_i = tls_i;                // Error in C and C++ 
    int j = j;                               // OK in C++, error in C
    Thread int tls_i = sizeof( tls_i )       // Legal in C and C++
    

    Observe que uma sizeof expressão inclui o objeto que está sendo inicializado não representa uma referência a mesmo e é habilitado em c e C++.

    C++ não permite tal inicialização dinâmica de dados de thread devido a possíveis futuros aprimoramentos para o recurso de armazenamento local de thread.

  • Em sistemas operacionais do Windows antes de Windows Vista, __declspec(thread) tem algumas limitações.Se uma DLL declara quaisquer dados ou objeto como __declspec(thread), ele pode causar uma falha de proteção se carregado dinamicamente.Depois que a DLL é carregada com LoadLibrary, ele causa uma falha do sistema sempre que o código faz referência a __declspecdados (thread).Porque o espaço de variável global para um thread é alocado em tempo de execução, o tamanho desse espaço é baseado em um cálculo de requisitos do aplicativo mais requisitos de todas as DLLs vinculadas estaticamente.Quando você usa LoadLibrary, não é possível estender esse espaço para as variáveis de segmento locais declaradas com __declspec(thread).Use as APIs de TLS, como TlsAlloc, na sua DLL alocar TLS se a DLL pode ser carregada com LoadLibrary.

Consulte também

Conceitos

Armazenamento Local de thread (TLS)