喜欢这个。
struct some_struct
{
// Other fields
.....
__thread int tl;
}
我正在尝试这样做,但编译器给了我这个错误。
./cv.h:16:2: error: '__thread' is only allowed on variable declarations
__thread int tl;
答案 0 :(得分:14)
线程局部存储仅适用于静态变量。将非静态结构或类成员线程局部化是没有意义的。
本地(自动)变量始终特定于执行代码的线程,但全局和静态变量在线程之间共享,因为它们驻留在数据或BSS段中。 TLS提供了一种机制,使这些全局变量成为线程的本地变量,这就是__thread
关键字所实现的 - 它指示编译器在每个线程中创建变量的单独副本,而词法上它仍然是全局变量(例如它可以通过在同一执行线程中调用的不同函数来访问。
非静态类成员和结构成员放置在分配对象(类或结构)的相同位置 - 如果声明了自动变量,则在堆栈上;如果是new
或{,则放在堆中{1}}被使用。无论哪种方式,每个线程都会收到变量的唯一存储位置,malloc()
在这种情况下不适用,因此会出现编译错误。
答案 1 :(得分:7)
gcc
对使用__thread
强制执行以下restrictions:
__thread
说明符可以应用于类的任何全局,文件范围的静态,函数范围的静态或静态数据成员。它可能不适用于块范围的自动或非静态数据成员。
多个编译器支持__thread
修饰符。从编译器到编译器的确切限制有所不同,这是不可想象的。
答案 2 :(得分:4)
C11标准第6.7.1节第2段
最多可以在a中的声明说明符中给出一个存储类说明符 声明,但_Thread_local可能出现在static或extern.120)
C11标准第6.7.1节第3段
在具有块作用域的对象的声明中,如果声明说明符包含 _Thread_local,它们还应包括静态或外部。如果 _Thread_local出现在对象的任何声明中,它应出现在每个对象中 声明该对象。
答案 3 :(得分:3)
您应该将__thread int tl;
更改为thread_local static int tl;
答案 4 :(得分:2)
根据旧的Petzold书“Programming Windows”(第1241页),您可以使用关键字将变量标记为本地线程:__ declspec(thread)。 例如: __declspec(thread)int iGlobal = 1;
我怀疑这可以在课堂上完成。您也可以将变量设置为静态。 [编辑]刚刚意识到你可能没有在Windows上运行......所以我想对于任何需要Windows回答的人来说,这可能是相关的。
答案 5 :(得分:0)
对于C来说这没有多大意义,static
(=全局)成员只是C ++的一个特性。因此新的C11标准(引入_Thread_local
)不允许它。这些野兽基本上都是允许的,只允许使用具有静态存储持续时间的变量。
对于C ++,这在类中可能与static
成员类似,但如果C ++ 11允许这样做,我不知道。
答案 6 :(得分:0)
这样写:
template <class T> struct S {
thread_local static int tlm;
};
template <> thread_local int S<float>::tlm = 0; // "static" does not appear here
如https://en.cppreference.com/w/cpp/language/storage_duration
中所述答案 7 :(得分:0)
您可以将thread_local
用于C ++中的类或结构的static
成员。
struct some_struct
{
// Other fields
.....
thread_local static int tl;
}
应该没问题。因此some_struct::tl
在不同的线程中可以具有不同的值。
如果要定义它,则必须再次添加thread_local
:
thread_local int some_struct::tl = 10;
答案 8 :(得分:0)
您还可以将结构本身指定为线程本地。例如;
#include <pthread.h>
thread_local struct gl_i_t{
int a;
int b;
}GL_i_t;
然后您可以在线程内使用GL_i_t变量。