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