Linux的线程本地存储实现

ano*_*non 29 linux multithreading gcc thread-local-storage

__thread Foo foo;
Run Code Online (Sandbox Code Playgroud)

"foo"如何实际解决?编译器是否以函数调用静默替换"foo"的每个实例?"foo"存储在相对于堆栈底部的某处,并且编译器将其存储为"嘿,对于每个线程,将此空间放在堆栈底部附近,并将foo存储为'堆栈底部的偏移x' "?

Dea*_*ing 34

它有点复杂(本文档详细解释了它),但它基本上都没有.而是编译器在可执行文件中放置一个特殊的.tdata部分,其中包含所有线程局部变量.在运行时,使用(只读).tdata部分中的数据副本创建每个线程的新数据部分,并且在运行时切换线程时,该部分也会自动切换.

最终结果是__thread变量和常规变量一样快,并且它们也不占用额外的堆栈空间.

  • 对于懒得阅读附件的人来说,缺失的部分是线程本地存储区域的地址存储在GS段寄存器(x86-64中的FS)中,所以要访问TLS,你只需要执行mov eax, GS:PTR. (21认同)
  • 我不相信你可以,但是单个变量的地址会有所不同,所以你可以从不同的线程打印出单个__thread变量的地址,看看它们是不同的. (3认同)