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。