2010-09-17 8 views

Respuesta

13

Lea el Wikipedia entry.

El almacenamiento local de subprocesos no es algo particular de C++. Algunas veces recibe diferentes nombres, como "TLS" (solo abreviatura de almacenamiento local de subprocesos) o "almacenamiento específico de subprocesos" (TSS).

La mayoría de los sistemas operativos proporcionan API para acceder al almacenamiento por subproceso. Por ejemplo, Windows tiene un bunch of API functions comenzando con "TLS". Bajo el capó, Win32 reserva un área especial para una variedad de datos por subproceso, incluido el almacenamiento local de subprocesos de usuario, accesible a través de un registro de CPU particular (FS en x86). Linux proporciona almacenamiento específico de subprocesos a través de las API pthread, con nombres como pthread_key_create, y estos generalmente se implementan usando una técnica similar.

Es posible que un sistema operativo no proporcione ningún tipo de soporte. Sin embargo, si el sistema operativo proporciona un ID de subproceso único de proceso a través de una API, entonces la biblioteca de tiempo de ejecución C++ podría mantener algo conceptualmente como un std::map<thread_id, per_thread_storage> internamente. Por supuesto, entonces hay un problema de qué es per_thread_storage. Si un programa estaba enlazado estáticamente, podría ser algo así como un puntero a una estructura grande con todas las variables de almacenamiento locales de subprocesos declaradas en el programa como elementos. Esto es una simplificación excesiva, pero se entiende la idea general.

El acceso a las variables de almacenamiento locales de subprocesos obviamente no es solo una lectura o escritura de memoria recta. Es potencialmente un poco más complicado que eso. Si va a utilizar mucho el almacenamiento local/específico de subprocesos en una función particular, le recomiendo que primero copie el puntero de almacenamiento local de subprocesos en una variable local.

+2

Ha respondido cómo un desarrollador de aplicaciones puede implementar TLS pero no cómo el compilador y el cargador manejan la palabra clave thread_local de C++ 0x – doron

+6

@ doron: el compilador y el cargador utilizan las API proporcionadas por el sistema operativo, o hacen algo equivalente a la técnica del mapa, sin que el programador tenga que escribir ningún código. – Doug

4

Las variables globales (o datos estáticos grabables - WSD) normalmente se almacenan en un bloque de memoria separado de la pila, el montón y el código. El bloque WSD se crea e inicializa antes de que el código del ejecutable comience a ejecutarse.

C++ 0x introduce la palabra clave thread_local que garantiza que se crea una instancia separada de la variable global por subproceso. El problema es que se debe cargar un bloque diferente por hilo.

La siguiente dificultad es que la dirección de la variable no se fija en el tiempo del enlace y es diferente para cada hilo.

Existen dos formas de solucionar este problema. Una es para que el compilador genere una llamada de función para obtener el bloque correcto, mientras que la otra es para cambiar el ABI para almacenar el bloque TLS en uno de los registros del procesador. Esto se puede usar con compensaciones para acceder a la variable correcta thread_local.

Esto es diferente del soporte de biblioteca donde el sistema operativo almacena un único valor void* que se puede usar almacena un puntero a un bloque local de subproceso que se ha asignado en el montón de proceso.

Si desea los detalles sangrientos, busque here.

0

Puede usar boost::thread para manejar portables TLS en diferentes plataformas. La implementación en cada uno está en el código y debería ayudarlo a comprender cómo los diferentes sistemas manejan esta área.

+1

En C++ 0x, el compilador admite TLS con la palabra clave thread_local – doron

+0

El uso de boost es correcto, pero para el registro algunos compiladores realmente han comprado en el espacio problemático. http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html –

+0

Tienes razón, voy a actualizar esto. –

Cuestiones relacionadas