【问题标题】:Linux's thread local storage implementationLinux的线程本地存储实现
【发布时间】:2010-03-17 03:16:04
【问题描述】:
__thread Foo foo;

“foo”实际上是如何解决的?编译器是否用函数调用静默替换“foo”的每个实例? “foo”是否存储在相对于堆栈底部的某个位置,编译器将其存储为“嘿,对于每个线程,在堆栈底部附近有这个空间,而 foo 存储为'offset x from the bottom of stack' “?

【问题讨论】:

    标签: linux multithreading gcc thread-local-storage


    【解决方案1】:

    这有点复杂(this document 解释得很详细),但基本上两者都不是。相反,编译器会在可执行文件中放置一个特殊的 .tdata 部分,其中包含所有线程局部变量。在运行时,会为每个线程创建一个新的数据段,其中包含(只读).tdata 段中的数据副本,并且在运行时切换线程时,该段也会自动切换。

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

    【讨论】:

    • 如果我有多个线程但只有一个内核,我可以看到它是如何工作的。当我有多线程和多核时,这个 .tdata 部分如何工作?
    • @anon:Linux 线程实际上是独立的进程,它们的大部分资源共享(例如它们的大部分内存空间),但并非所有资源都必须共享; man 2 clone 可能会有所帮助。您可以针对您描述的情况编写一个测试程序。
    • 如何打印出属于特定线程的.tdata的地址?
    • 我不相信你可以,但是各个变量的地址会有所不同,所以你可以从不同的线程打印出单个 __thread 变量的地址,看看它们是不同的。
    • 对于懒得看附件的人来说,缺少的部分是线程本地存储区域的地址存储在GS段寄存器(x86-64中的FS)中,所以要访问 TLS 你只需 mov eax, GS:ptr.
    猜你喜欢
    • 2014-06-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多