考虑以下示例(为简单起见省略了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),如果建造,应在线程退出。
也有可能对象是在其他时间构造的(例如在程序启动时),因为"在第一次使用之前"意味着"在任何时候,只要它在之前"而不是"就在之前"。