C++ 是C++;11线程\u局部变量自动静态?

C++ 是C++;11线程\u局部变量自动静态?,c++,c++11,thread-local-storage,C++,C++11,Thread Local Storage,这两个代码段之间是否存在差异: void f() { thread_local vector<int> V; V.clear(); ... // use V as a temporary variable } void f(){ 局部向量V; V.清除(); …//使用V作为临时变量 } 及 void f(){ 静态线程_局部向量V; V.清除(); …//使用V作为临时变量 } 背景故事:最初我有一个静态向量V(用于保存一些中间值,每次我进入函数时它都

这两个代码段之间是否存在差异:

void f() {
    thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}
void f(){
局部向量V;
V.清除();
…//使用V作为临时变量
}

void f(){
静态线程_局部向量V;
V.清除();
…//使用V作为临时变量
}

背景故事:最初我有一个静态向量V(用于保存一些中间值,每次我进入函数时它都会被清除)和一个单线程程序。我想把程序变成一个多线程的程序,所以我必须摆脱这个静态修饰符。我的想法是将每个静态都转换为线程本地,而不必担心其他任何事情?这种方法会适得其反吗?

是的,“线程本地存储”与“全局”(或“静态存储”)非常相似,只是“整个程序的持续时间”与“整个线程的持续时间”不同。所以,块局部线程局部变量初始化时,第一次控制通过其声明,但在每个线程中单独进行,线程结束时销毁。< / P> < P>根据C++标准

当线程_local应用于块范围的变量时 如果未显示存储类说明符static,则表示该说明符为 明确地

这意味着这个定义

void f() {
    thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}
void f(){
局部向量V;
V.清除();
…//使用V作为临时变量
}
相当于

void f() {
    static thread_local vector<int> V;
    V.clear();
    ... // use V as a temporary variable
}
void f(){
静态线程_局部向量V;
V.清除();
…//使用V作为临时变量
}
但是,静态变量与线程局部变量不同

1使用thread\ U local关键字声明的所有变量都具有thread 存储时间。这些实体的存储时间应为 创建它们的线程的持续时间。有一个明显的区别 对象或每个线程的引用,并且使用声明的名称引用 与当前线程关联的实体


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

线程本地存储是静态的,但其行为与简单的静态存储截然不同

当您声明一个静态变量时,该变量只有一个实例。编译器/运行时系统保证在您实际使用它之前的某个时间为您初始化它,而不指定确切的时间(这里省略了一些细节)

C++11保证此初始化是线程安全的,但是在C++11之前,此线程安全没有得到保证。比如说

static X * pointer = new X;
如果多个线程同时命中静态初始化代码,则可能泄漏X实例

当您声明一个变量为本地线程时,该变量可能有许多实例。您可以将它们视为位于一个由thread-id索引的映射中。这意味着每个线程都可以看到自己的变量副本

同样,如果变量被初始化,编译器/运行时系统将保证在使用数据之前进行初始化,并且使用变量的每个线程都会进行初始化。编译器还保证初始化是线程安全的


线程安全保证意味着可以有相当多的幕后代码使变量按照您期望的方式运行——特别是考虑到编译器无法提前准确知道程序中将存在多少线程,以及其中有多少线程将接触线程局部变量。

何时与
thread\u local
一起使用,
static
隐含在块范围内(参见@Vlad的答案),对于类成员是必需的;我想,这意味着命名空间范围的链接

根据9.2/6:

在类定义中, 除非还声明为静态,否则不得使用thread_本地存储类说明符声明成员

回答原问题:

C++11线程_局部变量是否自动静态

除了名称空间范围变量之外,别无选择

这两个代码段之间是否存在差异:

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

不。

有一个
线程\u局部
局部变量是没有意义的…每个线程都有自己的调用堆栈。最初编写几个C函数是为了返回静态或全局变量的地址。后来发现,在多线程应用程序(如errno、localtime)中使用时,这会导致不明显的错误。此外,当从多个线程调用函数或必须在多个调用对象和方法之间传递线程上下文对象时,有时使用互斥来保护共享变量是非常有害的。。线程的局部变量解决了这些问题和其他问题。@Konrad Rudolph仅将局部变量声明为
静态
,而不是
静态线程\u local
,不会为每个线程初始化变量的一个实例。@davide这不是重点,无论是我还是OP。我们谈论的不是
static
vs
static thread\u local
,而是
auto
vs
thread\u local
,使用
auto
的前C++11含义(即自动存储)。另请参阅。一个快速的语言律师笔记。。。微软和TLS对Vista的支持发生了变化;看见这种变化会影响像Singleton这样的事情,可能适用也可能不适用。如果您使用的是abondware软件模型,那么您可能就可以了。如果您愿意支持多个编译器和平台,那么您可能需要注意。
static
extern
因此并不意味着存储类,而只是线程本地变量的链接,即使在内部作用域中。@Deduplicator Block scope变量也没有链接。所以你的简历是错的。正如我在文章中所写,它们有线程存储持续时间。事实上是这样