c++ c++11 thread-local-storage

¿C++ 11 thread_local variables automáticamente estático?



c++11 thread-local-storage (4)

¿Hay alguna diferencia entre estos dos segmentos de código?

void f() { thread_local vector<int> V; V.clear(); ... // use V as a temporary variable }

y

void f() { static thread_local vector<int> V; V.clear(); ... // use V as a temporary variable }

Trasfondo: originalmente tenía un vector STATIC V (para mantener algunos valores intermedios, se borra cada vez que ingreso a la función) y un programa de subproceso único. Quiero convertir el programa en uno de subprocesamiento múltiple, así que de alguna manera tengo que deshacerme de este modificador estático. ¿Mi idea es convertir cada estática en thread_local y no preocuparte por nada más? ¿Puede este enfoque ser contraproducente?


Sí, "almacenamiento local de subprocesos" es muy similar a "global" (o "almacenamiento estático"), solo que en lugar de "duración de todo el programa" tiene "duración de todo el subproceso". Por lo tanto, una variable de local local de bloque se inicializa la primera vez que el control pasa por su declaración, pero por separado dentro de cada hilo, y se destruye cuando termina el hilo.


El almacenamiento local de subprocesos es estático pero se comporta de forma bastante diferente al almacenamiento estático simple.

Cuando declara una variable estática, hay exactamente una instancia de la variable. El sistema de compilación / tiempo de ejecución garantiza que se inicializará en algún momento antes de que realmente lo use, sin especificar exactamente cuándo (algunos detalles se omiten aquí).

C ++ 11 garantiza que esta inicialización será segura para los hilos, sin embargo, antes de C ++ 11, no se garantizaba la seguridad de este subproceso. Por ejemplo

static X * pointer = new X;

podría perder instancias de X si más de un hilo golpea el código de inicialización estática al mismo tiempo.

Cuando declara un subproceso de variable local, hay potencialmente muchas instancias de la variable. Podría pensar que están en un mapa indexado por id-thread. Eso significa que cada hilo ve su propia copia de la variable.

Una vez más, si la variable se inicializa, el sistema de compilación / tiempo de ejecución garantiza que esta inicialización ocurrirá antes de que se utilicen los datos y que la inicialización ocurrirá para cada hilo que use la variable. El compilador también garantiza que la iniciación será segura para subprocesos.

Las garantías de seguridad de subprocesos significa que puede haber bastante código detrás de escena para hacer que la variable se comporte de la manera que usted espera, especialmente si se tiene en cuenta que el compilador no tiene forma de saber exactamente cuántos subprocesos existen en su programa y cuántos de ellos tocarán la variable local del hilo.


De acuerdo con el estándar C ++

Cuando thread_local se aplica a una variable del ámbito del bloque, el static de la clase de almacenamiento está implícito si no aparece explícitamente.

Entonces significa que esta definición

void f() { thread_local vector<int> V; V.clear(); ... // use V as a temporary variable }

es equivalente a

void f() { static thread_local vector<int> V; V.clear(); ... // use V as a temporary variable }

Sin embargo, una variable estática no es lo mismo que una variable thread_local.

1 Todas las variables declaradas con la palabra clave thread_local tienen duración de almacenamiento de hilo. El almacenamiento para estas entidades durará por la duración del hilo en el que se crean. Hay un objeto distinto o referencia por hilo, y el uso del nombre declarado se refiere a la entidad asociada con el hilo actual

Para distinguir estas variables, el estándar introduce un nuevo término de duración de almacenamiento de subprocesos junto con la duración de almacenamiento estático.


Cuando se usa con thread_local , static está implícito en block-scope (ver la respuesta de @Vla), requerido para un miembro de la clase; Supongo que significa vinculación para el alcance del espacio de nombres.

Por 9.2 / 6:

Dentro de una definición de clase, un miembro no se declarará con el especificador de clase de almacenamiento hilo_local a menos que también se declare estático

Para responder la pregunta original:

¿C ++ 11 thread_local variables automáticamente estático?

No hay otra opción, excepto las variables de ámbito de espacio de nombres.

¿Hay alguna diferencia entre estos dos segmentos de código?

No.