thread

Específicos de Microsoft

El modificador de clase de almacenamiento extendida thread se usa para declarar una variable local para el subproceso. Para el portable equivalente en C++11 y versiones posteriores, use el especificador de clase de almacenamiento para el código portable thread_local. En Windows thread_local se implementa con __declspec(thread).

Sintaxis

__declspec(thread)declarator

Comentarios

El almacenamiento local para el subproceso (TLS) es el mecanismo por el que cada subproceso de un proceso con varios subproceso asigna almacenamiento para los datos específicos de ese subproceso. En los programas multiproceso estándar, los datos se comparten entre todos los subproceso de un proceso dado, mientras que el almacenamiento local para el subproceso es el mecanismo para asignar datos por subproceso. Para obtener un análisis completo de los subprocesos, consulte Multithreading.

Las declaraciones de variables locales para el subproceso deben utilizar la sintaxis de atributos extendida y la palabra clave __declspec con la palabra clave thread. Por ejemplo, el código siguiente declara una variable local de subproceso de entero y la inicializa con un valor:

__declspec( thread ) int tls_i = 1;

Al usar variables locales de subproceso en bibliotecas cargadas dinámicamente, se debe tener en cuenta los factores que pueden hacer que una variable local de subproceso no se inicialice correctamente:

  1. Si la variable se inicializa con una llamada de función (incluidos los constructores), solo se llamará a esta función para el subproceso que causó la carga del archivo binario o DLL en el proceso y para esos subprocesos que se iniciaron después de cargar el archivo binario o DLL. No se llama a las funciones de inicialización para ningún otro subproceso que ya se estaba ejecutando cuando se cargó el archivo DLL. La inicialización dinámica se produce en la llamada DllMain para DLL_THREAD_ATTACH, pero el archivo DLL nunca obtiene ese mensaje si el archivo DLL no está en el proceso cuando se inicia el subproceso.

  2. Las variables locales de subproceso que se inicializan estáticamente con valores constantes se inicializan normalmente correctamente en todos los subprocesos. Sin embargo, a partir de diciembre de 2017 hay una incidencia de conformidad conocida en el compilador de Microsoft C++ en el que las variables constexpr reciben la inicialización dinámica en lugar de estática.

    Nota: Se espera que ambos problemas se corrijan en futuras actualizaciones del compilador.

Además, se deben seguir estas instrucciones cuando se declaren objetos y variables locales para el subproceso:

  • Solo se puede aplicar el atributo thread a las declaraciones y definiciones de datos y a clases; thread no se puede usar en declaraciones o definiciones de función.

  • Solo se puede especificar el atributo thread en elementos de datos con duración de almacenamiento estática. Entre ellos se incluyen objetos de datos globales (tanto static como extern), objetos estáticos locales y miembros de datos estáticos de clases. No se pueden declarar objetos de datos automáticos con el atributo thread.

  • Se debe usar el atributo thread para la declaración y definición de un objeto local para el subproceso, tanto si la declaración y la definición se realizan en el mismo archivo como en archivos distintos.

  • No se puede usar el atributo thread como modificador de tipo.

  • Como la declaración de objetos que usan el atributo thread está permitida, los dos ejemplos siguientes son semánticamente 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.
    
  • El estándar de C permite la inicialización de un objeto o de una variable con una expresión que contenga una referencia a sí misma, pero solo para objetos no estáticos. Aunque C++ normalmente permite esa inicialización dinámica de objetos con una expresión que contenga una referencia a sí misma, este tipo de inicialización no se permite con objetos locales de un subproceso. Por ejemplo:

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

    Una expresión sizeof que incluye el objeto que se está inicializando no representa una referencia a sí misma y se permite en C y en C++.

FIN de Específicos de Microsoft

Consulte también

__declspec
Palabras clave
Almacenamiento local de subprocesos (TLS)