注册为线程局部变量

时间:2012-04-03 14:15:25

标签: c linux x86-64

在gcc中,您可以声明一个线程局部变量,例如,如下所示。

__thread long thread_local_variable;

此外,在gcc中,您可以指定一个变量来使用某个寄存器,例如,如下所示。

long register_variable asm ("r15" );

我想结合这两个概念,也就是说,我想声明一个使用某个寄存器的线程局部变量。我怎样才能做到这一点?

4 个答案:

答案 0 :(得分:3)

如果你考虑一下,那就行不通了。

对于线程局部变量,每个线程都需要它自己的存储实例。只有一个r15寄存器(或者每个核心一个。更准确地说是一个),所以根本没有地方可以存储其他线程。

另外,将其加入GCC's documentation's条款:

  

__thread说明符可以单独使用,使用extern或static说明符,但不能使用其他存储类说明符。

the register关键字是存储类说明符,因此不能与__thread一起使用。

答案 1 :(得分:3)

你不需要做任何特别的事情。你的例子:

long register_variable asm ("r15" );

已经声明了一个线程局部变量,仅仅是因为每个线程都有自己的一组寄存器值。

没有办法让GCC的全局寄存器存储变量在线程之间共享。事实证明,这没有得到很好的记录,这说明了寄存器存储全局变量的整体想法是多么糟糕和糟糕...

答案 2 :(得分:1)

当线程换出时,它们通常会将处理器的整个寄存器状态保存到某个堆栈中。线程恢复后,寄存器状态从存储器读回寄存器。

所以,如果您使用的语言允许它,那么理论上你可以做到这一点。每个线程在运行时都有自己的r15寄存器副本。然而...

GCC线程存储就是这样设计的。它将数据存储在某个RAM的RAM中,因此您可以稍后将指针传递给另一个线程。

答案 3 :(得分:1)

如果你想到它,你不需要任何特别的东西。 register变量的生命周期始终是定义它们的函数的当前调用。这些始终是“线程本地”变量。

gcc扩展程序__thread和C11功能_Thread_local是完全不同的概念。它们指定在每个线程基础上实例化静态存储的变量。这些变量绝不是register个变量。 C中的register关键字禁止您获取变量的地址,并强制该变量与auto变量类似。