什么时候初始化thread_local全局变量?



考虑以下示例(为简单起见省略了cout上的锁保护)。

#include <future>
#include <iostream>
#include <thread>
using namespace std;
struct C
{
  C() { cout << "C constructorn";}
  ~C() { cout << "C destructorn";}
};
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',此程序不输出任何内容,而如果用户输入非零数字,则将Constructor/Destructor打印10次。此外,clang抱怨一个明显未使用的表达式结果。

由于thread_local存储生命周期应该跨越整个线程的生命周期,因此我希望在每个线程中初始化foo变量,而不管用户输入是什么。

我可能想要一个thread-local变量,只是为了在构造函数中产生副作用,标准是否要求thread_local对象在第一次使用时初始化?

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

具有线程存储时间的变量应该在初始化之前其第一次使用(3.2),如果建造,应在线程退出。

也有可能对象是在其他时间构造的(例如在程序启动时),因为"在第一次使用之前"意味着"在任何时候,只要它在之前"而不是"就在之前"。

最新更新