¿Puedes usar variables locales de subprocesos dentro de una clase o estructura?

Me gusta esto.

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;

preguntado el 12 de junio de 12 a las 15:06

Por favor, publique el error del compilador que está recibiendo. -

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

9 Respuestas

En C y C++, el almacenamiento local de subprocesos se aplica solo a variables estáticas o variables con enlace externo.

Las variables locales (automáticas) generalmente se crean en la pila y, por lo tanto, son específicas del subproceso que ejecuta el código, pero las variables globales y estáticas se comparten entre todos los subprocesos, ya que residen en el segmento de datos o BSS. TLS proporciona un mecanismo para hacer que esas variables globales sean locales para el subproceso y eso es lo que __thread La palabra clave logra: le indica al compilador que cree una copia separada de la variable en cada subproceso, mientras que léxicamente sigue siendo global o estática (por ejemplo, se puede acceder a ella mediante diferentes funciones llamadas dentro del mismo subproceso de ejecución).

Los miembros de clase no estáticos y los miembros de estructura se colocan donde se asigna el objeto (clase o estructura), ya sea en la pila si se declara una variable automática o en el montón si new or malloc() se usa De cualquier manera, 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 obtienes.

Respondido el 15 de junio de 20 a las 12:06

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, bien envuelto detrás de alguna interfaz. - PlasmaHH

No estoy de acuerdo: el hecho de que un objeto sea creado por un solo subproceso no significa que será manipulado únicamente por un subproceso (por ejemplo, estructuras de datos sin bloqueo). Es cierto que esto es relativamente raro, sin embargo. - Cameron

Apreciaría si alguno de los votantes negativos quisiera publicar un contraejemplo o una mejor respuesta o brindar sugerencias sobre cómo editar la pregunta o editar la pregunta ellos mismos. - cristo iliev

@BeeOnRope Aprecio tu comentario y eliminé la generalización. - cristo iliev

gcc impone lo siguiente restricciones sobre el uso de __thread:

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

La __thread El modificador es compatible con varios compiladores. No es inconcebible que las restricciones exactas varíen un poco de un compilador a otro.

Respondido el 12 de junio de 12 a las 15:06

Deberías cambiar __thread int tl; a thread_local static int tl;

Respondido 01 Jul 14, 03:07

Entonces no puede tener múltiples instancias de la estructura/clase con diferentes valores en este campo. - oxidado

@rustyx: Por supuesto, puede tener diferentes valores en ese campo: cada hilo tendrá su propio valor. Lo que no puede tener con C++ estándar es un thread_local miembro normal: Tal tendría un valor diferente para cada objeto y cada hilo. - Kai Petzke

No sé, tal vez sería bueno tener diferentes valores por combinación de clase de subproceso. - Zendel

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

Como máximo, se puede proporcionar un especificador de clase de almacenamiento en los especificadores de declaración en una declaración, excepto que _Thread_local puede aparecer con static o extern.120)

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

En la declaración de un objeto con alcance de bloque, si los especificadores de declaración incluyen _Thread_local, también incluirán static o extern. Si _Thread_local aparece en cualquier declaración de un objeto, estará presente en cada declaración de ese objeto.

Respondido el 12 de junio de 12 a las 16:06

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

Corregido. Hábito de escribir C99. - foxis

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

Sin embargo, dudo que esto se pueda hacer en una clase. También puede hacer que la variable sea estática. [editar] Me acabo de dar cuenta de que probablemente no esté ejecutando Windows ... Así que supongo que para cualquiera que necesite una respuesta de Windows, esto puede ser relevante.

Respondido el 12 de junio de 12 a las 15:06

¿Por qué no debería funcionar __declspec (hilo) para las variables definidas en el método de clase? No estoy siendo sarcástico, ya que noto que ALGUNAS variables (punteros) definidas como estáticas parecen corromperse -1, lo cual es desconcertante - user3181125

Escribe de esta manera:

template <class T> struct S {
    thread_local static int tlm;
};
template <> thread_local int S<float>::tlm = 0; // "static" does not appear here

como se indica en https://en.cppreference.com/w/cpp/language/storage_duration

contestado el 14 de mayo de 19 a las 07:05

También puede especificar la estructura en sí como subproceso local. Por ejemplo;

#include <pthread.h>

thread_local struct gl_i_t{
    int a; 
    int b;
}GL_i_t;

Luego puede usar variables GL_i_t dentro del hilo.

Respondido el 06 de diciembre de 20 a las 08:12

Para C esto no tiene mucho sentido, static Los miembros (= globales) son solo una característica de C++. Y así, 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 de forma análoga a un static miembro, pero si esto está permitido por C ++ 11, no tengo idea.

Respondido el 12 de junio de 12 a las 16:06

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

Puedes usar el thread_local para static miembros de una clase o estructura en C++.

struct some_struct
{
 // Other fields
 .....
 thread_local static int tl;
}

Esto debería estar bien. Entonces some_struct::tl podría tener diferentes valores en diferentes subprocesos. Si quieres definirlo, tienes que añadir thread_local nuevo:

thread_local int some_struct::tl = 10;

Respondido 29 Oct 20, 13:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.