Je n'ai malheureusement jamais pu trouver un moyen de le faire.
Sans une sorte de crochet d'initialisation de thread, il ne semble tout simplement pas y avoir de moyen d'accéder à ce pointeur (à moins de hacks ASM qui dépendraient de la plate-forme).
Si vous voulez des variables locales de thread qui ne sont pas locales, pourquoi n'utilisez-vous pas des variables globales à la place ?
Clarification importante !
Je ne suggère pas que vous utilisiez un seul global pour remplacer une variable locale de thread. Je suggère d'utiliser un seul tableau global ou une autre collection appropriée de valeurs pour remplacer une variable locale de thread.
Vous devrez fournir une synchronisation bien sûr, mais puisque vous voulez exposer une valeur modifiée dans le thread A au thread B, il n'y a pas moyen de contourner cela.
Mise à jour :
La documentation GCC sur __thread
dit :
Lorsque l'opérateur d'adresse de est appliqué à une variable locale de thread, il est évalué au moment de l'exécution et renvoie l'adresse de l'instance de thread en cours de cette variable. Une adresse ainsi obtenue peut être utilisée par n'importe quel thread. Lorsqu'un thread se termine, tous les pointeurs vers les variables locales du thread dans ce thread deviennent invalides.
Par conséquent, si vous insistez pour suivre cette voie, j'imagine qu'il est possible d'obtenir l'adresse d'une variable locale de thread à partir du thread auquel elle appartient, juste après la génération du thread. Vous pouvez ensuite stocker un pointeur vers cet emplacement mémoire dans une carte (thread id => pointeur) et laisser d'autres threads accéder à la variable de cette façon. Cela suppose que vous possédez le code du thread généré.
Si vous êtes vraiment aventureux, vous pouvez essayer de trouver des informations sur ___tls_get_addr
(commencez par ce PDF auquel sont liés les documents GCC susmentionnés). Mais cette approche est tellement spécifique au compilateur et à la plate-forme et manque tellement de documentation qu'elle devrait déclencher des alarmes dans la tête de n'importe qui.
Je recherche la même chose. Comme je vois que personne n'a répondu à votre question après avoir cherché sur le Web de toutes les manières, je suis arrivé à l'information suivante :en supposant de compiler pour gcc sur linux (ubuntu) et en utilisant -m64, le registre de segment gs contient la valeur 0. La partie cachée du segment (contenant l'adresse linéaire) pointe vers la zone locale spécifique au thread. Cette zone contient à cette adresse l'adresse de cette adresse ( 64 bits ). Aux adresses inférieures sont stockées toutes les variables locales de thread. Cette adresse est le native_handle()
Ainsi, pour accéder aux données locales d'un thread, vous devez le faire via ce pointeur.
En d'autres termes :(char*)&variable-(char*)myThread.native_handle()+(char*)theOtherThread.native_handle()
Le code qui illustre ce qui précède en supposant g++,linux,pthreads est :
#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;
}