你可以在类或结构中使用线程局部变量吗?

时间:2012-06-12 14:49:50

标签: c++ c multithreading thread-local

喜欢这个。

struct some_struct
{
 // Other fields
 .....
 __thread int tl;
}

我正在尝试这样做,但编译器给了我这个错误。

./cv.h:16:2: error: '__thread' is only allowed on variable declarations
        __thread int tl;

9 个答案:

答案 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变量。