【问题标题】:thread local storage macosx线程本地存储macosx
【发布时间】:2010-03-13 00:40:39
【问题描述】:

http://developer.apple.com/mac/library/documentation/DeveloperTools/gcc-4.0.1/gcc/Thread_002dLocal.html

文档 __thread

但我的 g++ 抱怨我的拱门不支持 __thread(Macbookpro 上的 Leopard)。

这是为什么?我该如何解决?

【问题讨论】:

    标签: thread-local-storage


    【解决方案1】:

    将您的 gcc 升级到 gcc-4.5 或更高版本(通过 macports 或其他方式)。 mac 上的 TLS 操作比在 linux 或其他 unix 上要昂贵得多,因为它是模拟的。

    以下代码:

    __thread int foo; 无效 f() { ++富; }

    在 linux 上,它会被翻译成这样:

    F: 推%ebp movl %esp, %ebp movl %gs:foo@NTPOFF, %eax 添加 $1, %eax movl %eax, %gs:foo@NTPOFF 流行 %ebp ret

    但是在mac上,它会被翻译成这个(两个函数调用!!):

    _F: LFB0: pushq %rbp LCFI0: movq %rsp, %rbp LCFI1: pushq %rbx LCFI2: subq $8, %rsp LCFI3: leaq ___emutls_v.foo(%rip), %rdi 调用 ___emutls_get_address movl (%rax), %eax leal 1(%rax), %ebx leaq ___emutls_v.foo(%rip), %rdi 调用 ___emutls_get_address movl %ebx, (%rax) addq $8, %rsp 流行音乐 %rbx 离开 LCFI4: ret

    【讨论】:

    • Apple 技术实验室对此很愚蠢。他们说他们不想浪费一个寄存器并使其不兼容,而没有意识到段寄存器不再有其他用途。真的很烂。即使“__emutls_get_address”只是执行相同的单个 movl 指令。因此,如果有人足够勇敢,他们可以像在 linux 上那样手动将其编码为汇编程序内联。顺便问一下,这是真正的拆解吗?我一直以为是FS用来做TLS
    • 你不能“仅仅手动编码”,因为使用fsgs需要mac内核在GDT表中设置段基地址。
    【解决方案2】:

    我相信该页面只是标准 GCC 手册上的 Apple 样式表。注意 Mac OS X 中的 .so 而不是 .dylib

    所以 Mac 上的 gcc 完全有可能不支持__thread。您需要手动使用pthread_setspecific

    (This problem has been filed as a bug.)

    【讨论】:

    • 根据The Linux Programming Interface: A Linux and UNIX System Programming Handbook 中的Kerrisk,线程本地存储需要GCC 3.3 或更高版本(静态和全局声明为__thread)。 Mac OS X 附带 GCC 4.2,因此看起来 Apple 删除了该功能(或者没有将其移植回来)。它还需要内核支持(Linux 2.6 及更高版本)。这或许可以解释为什么 Apple 没有提供它。
    • 这是否意味着我们仍然无法在 mac os x (10.10) 上编译我在尝试安装 PyMetis (pip install pymetis) 和我的 gcc --version 报告时遇到了同样的问题:Apple LLVM version 7.0.2 (clang-700.1.81) Target: x86_64-apple-darwin14.5.0 Thread model: posix但是,我使用 brew install gcc49 安装了 gcc v 4.9
    猜你喜欢
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2011-01-04
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    相关资源
    最近更新 更多