suma pthread procesos libreria hilos ejercicios ejemplos dev con compilar c++ linux multithreading gcc thread-local-storage

c++ - pthread - Acceder al hilo local desde otro hilo.



pthread libreria (3)

¿Cómo puedo leer / escribir una variable local de hilo desde otro hilo? Es decir, en Thread AI le gustaría acceder a la variable en el área de almacenamiento local de subprocesos del Thread B. Conozco la ID del otro hilo.

La variable se declara como __thread en GCC. La plataforma de destino es Linux, pero la independencia podría ser agradable (sin embargo, el GCC específico está bien).

Al no tener un enlace de inicio de hilo, no hay forma de que pueda simplemente rastrear este valor al comienzo de cada hilo. Todos los hilos deben seguirse de esta manera (no solo los especialmente iniciados).

Una envoltura de nivel superior como boost thread_local_storage o usar pthread keys no es una opción. Requiero el rendimiento de usar una verdadera variable local de __thread .

LA PRIMERA RESPUESTA ES INCORRECTA : No se pueden usar variables globales para lo que quiero hacer. Cada hilo debe tener su propia copia de la variable. Además, esas variables deben ser __thread variables por razones de rendimiento (una solución igualmente eficiente también estaría bien, pero no conozco ninguna). Tampoco controlo los puntos de entrada del hilo, por lo que no es posible que esos hilos registren ningún tipo de estructura.

El hilo local no es privado : otro malentendido sobre las variables locales del hilo. Estos no son de ninguna manera un tipo de variable privada para el hilo. Son memorias direccionables globalmente, con la restricción de que su vida útil está vinculada al hilo. Cualquier función, desde cualquier subproceso, si se le asigna un puntero a estas variables, puede modificarlas. La pregunta anterior es esencialmente acerca de cómo obtener esa dirección de puntero.


Estoy buscando lo mismo. Como veo, nadie ha respondido a su pregunta después de haber buscado en la web de todas las maneras en que llegué a la siguiente información: suponiendo que compile gcc en linux (ubuntu) y use -m64, el registro de segmento gs tiene el valor 0. La parte oculta del segmento (que contiene la dirección lineal) apunta al área local específica del hilo. Esa área contiene en esa dirección la dirección de esa dirección (64 bits). En las direcciones inferiores se almacenan todas las variables locales de hilo Esa dirección es el native_handle() . Entonces, para acceder a un hilo de datos locales, debe hacerlo a través de ese puntero.

En otras palabras: (char*)&variable-(char*)myThread.native_handle()+(char*)theOtherThread.native_handle()

El código que demuestra lo anterior que supone g ++, linux, pthreads es:

#include <iostream> #include <thread> #include <sstream> thread_local int B=0x11111111,A=0x22222222; bool shouldContinue=false; void code(){ while(!shouldContinue); std::stringstream ss; ss<<" A:"<<A<<" B:"<<B<<std::endl; std::cout<<ss.str(); } //#define ot(th,variable) //(*( (char*)&variable-(char*)(pthread_self())+(char*)(th.native_handle()) )) int& ot(std::thread& th,int& v){ auto p=pthread_self(); intptr_t d=(intptr_t)&v-(intptr_t)p; return *(int*)((char*)th.native_handle()+d); } int main(int argc, char **argv) { std::thread th1(code),th2(code),th3(code),th4(code); ot(th1,A)=100;ot(th1,B)=110; ot(th2,A)=200;ot(th2,B)=210; ot(th3,A)=300;ot(th3,B)=310; ot(th4,A)=400;ot(th4,B)=410; shouldContinue=true; th1.join(); th2.join(); th3.join(); th4.join(); return 0; }


Lamentablemente, nunca pude encontrar una manera de hacer esto.

Sin algún tipo de enlace de inicio de hilo, parece que no hay una manera de llegar a ese puntero (menos los hacks ASM que serían dependientes de la plataforma).


Si desea variables locales de subprocesos que no son locales de subprocesos, ¿por qué no usa variables globales en su lugar?

¡Aclaración importante!

No estoy sugiriendo que use un solo global para reemplazar una variable de subproceso local. Estoy sugiriendo usar una única matriz global u otra colección adecuada de valores para reemplazar una variable de subproceso local.

Por supuesto, deberá proporcionar la sincronización, pero como desea exponer un valor modificado en el subproceso A al subproceso B, no hay forma de evitarlo.

Actualizar:

La documentación de GCC en __thread dice:

Cuando la dirección del operador se aplica a una variable de subproceso local, se evalúa en tiempo de ejecución y devuelve la dirección de la instancia del subproceso actual de esa variable. Una dirección así obtenida puede ser utilizada por cualquier hilo. Cuando un subproceso termina, cualquier puntero a las variables de subproceso local en ese subproceso se vuelve inválido

Por lo tanto, si insiste en ir de esta manera, me imagino que es posible obtener la dirección de una variable local del subproceso desde el subproceso al que pertenece, justo después de que se genera el subproceso. Luego, puede almacenar un puntero a esa ubicación de memoria en un mapa (thread id => puntero), y permitir que otros subprocesos accedan a la variable de esta manera. Esto supone que usted posee el código para el subproceso generado.

Si es realmente aventurero, puede intentar desenterrar información en ___tls_get_addr (comience desde este PDF que está vinculado por los documentos de GCC mencionados anteriormente). Pero este enfoque es tan específico para el compilador y la plataforma, y ​​por lo tanto carece de documentación que debería estar causando que las alarmas se disparen en la cabeza de cualquiera.