2012-06-12 8 views
18

Me gusta esto.Puede usar variables locales de subprocesos dentro de una clase o estructura

struct some_struct 
{ 
// Other fields 
..... 
__thread int tl; 
} 

Estoy tratando de hacer eso, pero el compilador me está dando este error.

./cv.h:16:2: error: '__thread' is only allowed on variable declarations 
     __thread int tl; 
+1

Por favor, después del error del compilador que está recibiendo. –

+0

AFAICS '__thread' no es estándar. ¿Qué compilador estás usando? –

Respuesta

12

almacenamiento local de subprocesos se aplica a las variables estáticas solamente. No tiene sentido hacer que la estructura no estática o los miembros de la clase se vuelvan locales.

Las variables locales (automáticos) son siempre específicos para el subproceso que ejecuta el código, pero las variables globales y estáticas son compartidos entre los hilos, ya que residen en el segmento de datos o BSS. TLS proporciona un mecanismo para hacer esas variables globales local al hilo y eso es lo que logra la palabra clave __thread - que indica al compilador para crear una copia separada de la variable en cada hilo, mientras léxico sigue siendo un problema mundial (por ejemplo, se puede acceder por diferentes funciones llamadas dentro del mismo hilo de ejecución).

miembros de la clase no estáticos y miembros de la estructura se colocan en el mismo lugar donde se asigna el objeto (clase o estructura) - o bien en la pila si se declara una variable automática o en el montón si se utiliza new o malloc(). De cualquier forma, cada subproceso recibe una ubicación de almacenamiento única para la variable y __thread simplemente no es aplicable en este caso, de ahí el error del compilador que obtiene.

+6

No con el significado actual de __thread o thread_local, pero hay bastantes situaciones en las que tiene sentido tener un miembro diferente para cada hilo, envuelto muy bien detrás de alguna interfaz. – PlasmaHH

+9

Tengo que estar en desacuerdo: el hecho de que un objeto sea creado por un único hilo no significa que se manipule únicamente por un hilo (por ejemplo, estructuras de datos sin bloqueo). Es cierto que esto es relativamente raro, sin embargo. – Cameron

+0

Agradecería que a alguno de los downvoters le interesara publicar un contraejemplo o una mejor respuesta o proporcionar sugerencias sobre cómo editar la pregunta o editar la pregunta ellos mismos. –

6

gcc aplica la siguiente restrictions en el uso de __thread:

El especificador __thread se puede aplicar a cualquier archivo de ámbito de la función de ámbito estático, o datos estáticos miembro mundial, estático, de un clase. No se puede aplicar a un miembro de datos automático o no estático con ámbito de bloque.

El modificador __thread es compatible con múltiples compiladores. No es inconcebible que las restricciones exactas varíen de un compilador a otro.

0

De acuerdo con el libro antiguo Petzold 'Programación de Windows' (página 1241) se marca una variable como hilo local utilizando las palabras clave: __declspec (rosca). Así, por ejemplo: __declspec (thread) int iGlobal = 1;

dudo que esto se podría hacer en una clase sin embargo. También puede hacer que la variable sea estática también. [edit] acaba de darse cuenta de que probablemente no se está ejecutando en Windows ... Así que supongo que para cualquiera que necesite una respuesta de Windows, esto puede ser relevante.

4

C11 estándar Sección 6.7.1 Párrafo 2

A lo sumo, un especificador de clase de almacenamiento se puede dar en los especificadores de declaración en una declaración , excepto que _Thread_local puede aparecer con estática o externo. 120)

C11 estándar Sección 6.7.1 Párrafo 3

En la declaración de un objeto con ámbito de bloque, si los especificadores de declaración incluyen _Thread_local, que también incluirá ya sea estática o externo. Si _Thread_local aparece en cualquier declaración de un objeto, debe estar presente en cada declaración de ese objeto.

+1

Supongo que te refieres a C11, ¿no? C99 no tenía un modelo de hilo y todo eso. –

+0

Corregido. Hábito de escribir C99. – phoxis

0

Para C esto no tiene mucho sentido, static (= global) los miembros son solo una característica de C++. Por eso, el nuevo estándar C11 (que introduce _Thread_local) no lo permite. Estas bestias están permitidas básicamente en todas partes donde se permite una variable con duración de almacenamiento estática.

Para C++ esto podría tener sentido dentro de una clase como análogo a un miembro static, pero si esto es permitido por C++ 11 no tengo ni idea.

+0

No parece permitido, obtuve C2720 con VS2015: https://msdn.microsoft.com/en-us/library/w8x1t4f0.aspx –

1

Debe cambiar __thread int tl;-thread_local static int tl;

+1

Entonces no puede tener varias instancias de la estructura/clase con valores diferentes en este campo. – rustyx

Cuestiones relacionadas