C++ “thread\u local”全局变量何时初始化?

C++ “thread\u local”全局变量何时初始化?,c++,multithreading,c++11,thread-local,C++,Multithreading,C++11,Thread Local,考虑以下示例,为简单起见,cout上的锁防护被省略 #include <future> #include <iostream> #include <thread> using namespace std; struct C { C() { cout << "C constructor\n";} ~C() { cout << "C destructor\n";} }; thread_local C foo; int mai

考虑以下示例,为简单起见,cout上的锁防护被省略

#include <future>
#include <iostream>
#include <thread>

using namespace std;

struct C
{
  C() { cout << "C constructor\n";}
  ~C() { cout << "C destructor\n";}
};

thread_local C foo;

int main()
{
   int select;
   cin >> select;
   future<void> f[10];
   for ( int i = 0;i < 10; ++i)
       f[i] = async( launch::async,[&](){ if (select) foo; } );
   return 0;
}
在clang和gcc上,如果用户写入“0”,此程序将不输出任何内容,而如果用户输入非零数字,则它将打印构造函数/析构函数10次。 另外,clang抱怨一个明显的未使用的表达式结果

因为一个线程的本地存储生命周期应该跨越整个线程的生命周期,所以我希望在每个线程中初始化foo变量,而不考虑用户输入


我可能想要一个线程局部变量,其唯一目的是在构造函数中产生副作用,标准是否要求线程局部对象在第一次使用时初始化?

标准允许这种行为,尽管它不能保证。从3.7.2/2[basic.stc.thread]:

具有线程存储持续时间的变量应在 其首次odr用途为3.2,如果建造,应在 线程退出


对象也可能是在其他时间构造的,例如在程序启动时,与之前一样,首次使用意味着在任何时间点,只要它是在之前,而不是刚刚之前。谢谢,我的CTRL+F技能非常有限:这有点误导;该标准规定,具有线程本地存储持续时间的变量必须在使用odr之前的某个时间进行初始化,但该标准并未规定初始化该变量的确切时间,甚至允许实现对该变量进行初始化,即使该变量从未使用过odr。如上所述:它最迟可以在使用odr变量时进行初始化,但这种初始化可以在使用odr变量之前的任何时候进行。@FilipRoséen refp:我昨天还不太清楚,如果按字面意思看,答案是这样的,但你在这两方面都是对的。我已经编辑,以明确第一次使用前是指在数学意义上。谢谢你的反馈。@shuva什么都不会改变。嗯。。。似乎全局线程的定义是局部的C foo;构成ODR使用。这与线程本地静态相反,线程本地静态是一个函数的本地静态,只有在输入该函数时才会使用ODR。我发现MSVC在没有使用的情况下创建了这些线程本地全局变量,而clang/gcc只在使用的情况下创建它们。