【问题标题】:Non-static global variable vs. global static __thread variable非静态全局变量与全局静态 __thread 变量
【发布时间】:2014-11-16 22:17:15
【问题描述】:

如果我在全局范围内定义一个静态__thread 变量,它是否等同于常规的非静态全局变量?换句话说,如果以下两个变量都在全局范围内,它们是否彼此等价:

int regular_global_int;
static __thread int static_thread_local_int;

如果答案是否定的,我能知道这两者之间的主要区别是什么,我应该什么时候使用哪一个?

【问题讨论】:

  • __thread 不是 C++11 标准的一部分,我相信它是 GCC 独有的。你是说thread_local吗?
  • 对不起,我的意思是 gcc 中的__thread。将更改标签。

标签: c++ multithreading gcc thread-local


【解决方案1】:

全局变量,以及更一般的命名空间范围变量,在未使用存储类说明符声明时自动具有静态存储持续时间。在命名空间范围内,static 并不意味着“静态存储持续时间”;这意味着变量具有内部链接。因此

int x;
static int x;

在命名空间范围内都声明 x 具有静态存储持续时间,但这两个声明与第一个声明提供 x 外部链接但第二个声明提供内部链接不同。

在你写的情况下

static thread_local int x;

thread_local 存储类说明符导致x 具有线程本地存储持续时间(而不是静态存储持续时间),而static 本身在命名空间范围内再次具有其通常含义。所以x 是线程本地的并且它有内部链接。

【讨论】:

  • 谢谢你的回答,但还是不太明白。那么具有静态存储持续时间的变量与具有线程本地 + 内部链接的变量之间有什么区别,它们的共同属性是什么?
  • @keelar 静态存储持续时间意味着该变量只有一个副本,并且它的生命周期在程序终止时结束。线程本地意味着每个线程有一个副本,并且它的生命周期在线程终止时结束。这完全独立于链接,它只是确定一个变量在其他翻译单元中是否可见。
  • 那么全局非静态变量呢?这是否意味着每个线程只有一个副本,并且它的生命周期也会在线程终止时结束?
  • @keelar 正如我所说,全局变量自动具有静态存储持续时间,即使它们未声明static。如果不是明确的thread_local,那么每个程序只有一个副本,并且它的生命周期在程序终止时结束。
  • 我想我明白了。谢谢你的解释:)
【解决方案2】:

我编译了

int regular_global_int;
__thread int static_thread_local_int;
int main()
{
 regular_global_int = 1;
 static_thread_local_int = 1;
}

http://ellcc.org/blog/?page_id=340 我不得不去掉静态变量以防止优化器摆脱静态变量。我得到了

main:                                   # @main
# BB#0:                                 # %entry
    movl    $1, regular_global_int(%rip)
    movl    $1, %fs:static_thread_local_int@TPOFF
    xorl    %eax, %eax
    retq

对于 x86_64。线程局部变量的访问方式不同,以提供线程局部存储。

【讨论】:

    猜你喜欢
    • 2015-06-12
    • 1970-01-01
    • 2022-01-28
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2018-04-28
    • 2012-10-04
    相关资源
    最近更新 更多