从另一个线程访问线程本地

如何从另一个线程读取/写入线程局部变量?也就是说,在线程A中,我想访问线程B的线程本地存储区域中的变量。我知道另一个线程的ID。 该变量在GCC中声明为
__thread
。目标平台是Linux,但独立性可能不错(但GCC具体可行)。 缺少线程启动挂钩,我无法在每个线程的开头简单地跟踪此值。需要以这种方式跟踪所有线程(不仅仅是特别启动的线程)。 像boost boost_local_storage或使用pthread键的更高级别的包装器不是一个选项。我要求使用真正的
__thread
局部变量。 第一个答案是错误的:人们不能将全局变量用于我想做的事情。每个线程必须有自己的变量副本。此外,出于性能原因,这些变量必须是
__thread
变量(同样有效的解决方案也可以,但我知道没有)。我也不控制线程入口点,因此这些线程不可能注册任何类型的结构。 线程本地不是私有的:另一个关于线程局部变量的误解。这些线程绝不是某种私有变量。它们是全局可寻址的内存,其限制是它们的生命周期与线程相关联。任何线程中的任何函数,如果给出指向这些变量的指针,都可以修改它们。上面的问题主要是关于如何获得指针地址。     
已邀请:
如果您想要非线程本地的线程局部变量,为什么不使用全局变量呢? 重要说明! 我不是建议您使用单个全局替换线程局部变量。我建议使用单个全局数组或其他合适的值集合来替换一个线程局部变量。 当然,您必须提供同步,但由于您希望将线程A中修改的值公开给线程B,因此无法解决这个问题。 更新: 关于
__thread
的海湾合作委员会文件说:   当运营商的地址是   应用于线程局部变量,它   在运行时进行评估并返回   当前线程的地址   该变量的实例。一个地址   如此获得的任何线程都可以使用。   当一个线程终止时,任何指针   到那里的线程局部变量   线程变得无效。 因此,如果你坚持这样做,我想可以在线程产生之后从它所属的线程中获取线程局部变量的地址。然后,您可以将指向该内存位置的指针存储到映射(thread id => pointer),并让其他线程以这种方式访问​​该变量。这假定您拥有生成的线程的代码。 如果你真的喜欢冒险,你可以尝试挖掘
___tls_get_addr
的信息(从这个由上述GCC文档链接的PDF开始)。但是这种方法具有如此高度的编译器和平台特性,因此缺乏文档,它应该导致警报在任何人的头脑中消失。     
我正在寻找同样的事情。 我看到在通过各种方式搜索网络后没有人回答你的问题后,我到达后续信息:假设在linux(ubuntu)上编译gcc并使用-m64,段寄存器gs保持值为0.隐藏部分段(保持线性地址) 指向线程特定的本地区域。 该区域在该地址包含该地址的地址(64位)。在较低地址存储所有线程局部变量。 那个地址是
native_handle()
。 因此,为了访问线程本地数据,您应该通过该指针进行操作。 换句话说:
(char*)&variable-(char*)myThread.native_handle()+(char*)theOtherThread.native_handle()
演示以上假设g ++,linux,pthreads的代码是:
#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;
}
    
遗憾的是我从来没有找到办法做到这一点。 如果没有某种线程初始化挂钩,那么似乎没有办法获得该指针(缺少与平台相关的ASM黑客)。     

要回复问题请先登录注册