Desafortunadamente, nunca pude encontrar una manera de hacer esto.
Sin algún tipo de enlace de inicio de subproceso, simplemente no parece haber una forma de llegar a ese puntero (aparte de los hacks de ASM que dependerían de la plataforma).
Si desea variables locales de subprocesos que no sean 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 local de subproceso. Estoy sugiriendo usar una única matriz global u otra colección adecuada de valores para reemplazar una variable local de subproceso.
Tendrá que proporcionar sincronización, por supuesto, pero dado que desea exponer un valor modificado en el subproceso A al subproceso B, no hay forma de evitarlo.
Actualización:
La documentación de GCC en __thread
dice:
Cuando el operador dirección de se aplica a una variable local de subproceso, 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 subproceso. Cuando un subproceso finaliza, cualquier puntero a las variables locales del subproceso en ese subproceso deja de ser válido.
Por lo tanto, si insiste en ir de esta manera, imagino que es posible obtener la dirección de una variable local de hilo del hilo al que pertenece, justo después de que se genera el hilo. Luego, puede almacenar un puntero a esa ubicación de memoria en un mapa (id de subproceso => puntero) y permitir que otros subprocesos accedan a la variable de esta manera. Esto supone que eres el propietario del código del hilo generado.
Si eres realmente aventurero, podrías intentar buscar información en ___tls_get_addr
(comience desde este PDF que está vinculado por los documentos GCC antes mencionados). Pero este enfoque es tan específico del compilador y de la plataforma y carece tanto de documentación que debería hacer que las alarmas salten en la cabeza de cualquiera.
Estoy buscando lo mismo. Como veo que nadie ha respondido a su pregunta después de haber buscado en la web de todas las formas, llegué a la siguiente información:suponiendo compilar para gcc en linux (ubuntu) y usando -m64, el segmento registra gs contiene el valor 0. La parte oculta del segmento (que contiene la dirección lineal) apunta al área local específica del subproceso. Esa área contiene en esa dirección la dirección de esa dirección (64 bits). En las direcciones más bajas se almacenan todas las variables locales del subproceso. Esa dirección es el native_handle()
Entonces, para acceder a los datos locales de un hilo, 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 suponiendo 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;
}