C ++ 11的thread_localvariables是否自动静态?

这两个代码段是否有区别:

void f() { thread_local vector<int> V; V.clear(); ... // use V as a temporary variable } 

 void f() { static thread_local vector<int> V; V.clear(); ... // use V as a temporary variable } 

Backstory:原本我有一个STATIC向量V(用于保存一些中间值,每当我进入函数时它都被清除)和一个单线程程序。 我想把程序变成一个multithreading,所以我不得不摆脱这个静态修饰符。 我的想法是将每个静态变成thread_local,而不是担心别的? 这种方法能适得其反吗?

根据C ++标准

当将thread_local应用于块范围的variables时,如果未明确显示,则存储类说明符static将被隐含

所以这意味着这个定义

 void f() { thread_local vector<int> V; V.clear(); ... // use V as a temporary variable } 

相当于

 void f() { static thread_local vector<int> V; V.clear(); ... // use V as a temporary variable } 

但是,一个静态variables与thread_localvariables不同。

1使用thread_local关键字声明的所有variables都具有线程存储持续时间。 这些实体的存储将在创build它们的线程的持续时间内持续存储。 每个线程都有独特的对象或引用,声明的名称的使用引用与当前线程关联的实体

为了区分这些variables,标准引入了新的术语线程存储持续时间以及静态存储持续时间。

是的,“线程本地存储”与“全局”(或“静态存储”)非常相似,只不过“整个程序的持续时间”而不是“整个线程的持续时间”。 所以一个块本地的线程局部variables在控制首次通过它的声明时被初始化,但是在每个线程中被分开,并且在线程结束时被销毁。

当和thread_local使用时, static被隐含在块范围内(参见@ Vlad的答案),为类成员所需; 我想,这意味着命名空间范围的链接。

每9.2 / 6:

在类定义中,除非声明为static,否则不应使用thread_local存储类指定符声明成员

回答原来的问题:

C ++ 11的thread_localvariables是否自动静态?

没有select,除了命名空间范围variables。

这两个代码段是否有区别:

没有。

线程本地存储是静态的,但它的行为与简单的静态存储非常不同。

当你声明一个variablesstatic时,这个variables只有一个实例。 编译器/运行时系统保证在你真正使用它之前,它会被初始化,而不需要指定什么时候(这里省略一些细节)。

C ++ 11保证这个初始化将是线程安全的,但是在C ++ 11之前,这个线程安全是不能保证的。 例如

 static X * pointer = new X; 

如果多个线程同时触发静态初始化代码,可能会泄露X的实例。

当你声明一个局部variables的线程时,这个variables可能有很多实例。 你可以把它们想象成一个由thread-id索引的地图。 这意味着每个线程都会看到自己的variables副本。

再一次,如果variables被初始化,编译器/运行时系统保证这个初始化将在数据被使用之前发生,并且每个使用该variables的线程都会发生初始化。 编译器还保证启动将是线程安全的。

线程安全性保证意味着可以有相当多的后台代码来使variables按照您期望的方式运行 – 特别是考虑到编译器无法提前知道究竟有多less线程存在于你的程序中,其中有多less将触及线程局部variables。