joh*_*ohn 5 c++ multithreading thread-local
我在文件 tracker.hpp 中有一个变量:
namespace TRIALS
{
static thread_local int a = -1;
}
Run Code Online (Sandbox Code Playgroud)
我在 ema.hpp/ema.cpp 中的文件中有另一个名为 EMP 的类
namespace Algo
{
class EMP
{
public:
void Sample();
};
}
Run Code Online (Sandbox Code Playgroud)
namespace Algo
{
void EMP::Sample()
{
std::cout << "model " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我的主文件
auto model = Algo::EMP();
void Simulate(const int a)
{
TRIALS::a = a;
model.Sample()
std::cout << "worker " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
}
int main()
{
std::cout << &TRIALS::a << std::endl;
const int nthreads = 1;
std::cout << "main " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
std::vector<std::thread> threads;
for(int i=0; i<nthreads; ++i)
{
threads.emplace_back(&Simulate, i);
}
for(auto &thread : threads)
{
thread.join();
}
std::cout << "main " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我只是运行一个线程进行调试,但这是输出:
0x7f9540b621d8
main 140279012532800 0x7f9540b621d8 -1 (如预期)
型号 140278985606912 0x7f953f1b469c -1 (这不应该是0吗?)
工人 140278985606912 0x7f953f1b4698 0 (如预期)
main 140279012532800 0x7f9540b621d8 -1 (如预期)
我的印象是每个线程都有它自己的 TRIALS::a 本地副本。模型中的 a 正确地递增,但是当它从同一线程中的函数返回时,该值仍然为 0。我正在打印线程 id 和 a 的地址以进行良好的测量,我发现实际上有 3 个不同的值尽管只有两个线程,但 TRIALS::a 的版本。
static thread_local int a作为一个额外问题,和之间有什么区别thread_local int a?
在您的示例中,static使该thread_local对象使用内部链接,以便每个翻译单元(.cpp 文件)都有自己的变量副本。
有关详细信息,请参阅存储类说明符:
该
thread_local关键字仅适用于在命名空间范围内声明的对象、在块范围内声明的对象以及静态数据成员。表明该对象具有线程存储持续时间。它可以与static或extern结合使用,分别指定内部或外部链接(除了始终具有外部链接的静态数据成员),但附加的静态不会影响存储持续时间。
也就是说,您可能想删除该static关键字,以便在整个应用程序中只有该对象的一份副本。在头文件中执行:
namespace TRIALS {
extern thread_local int a;
}
Run Code Online (Sandbox Code Playgroud)
并在其中之一.cpp:
thread_local int TRIALS::a = -1;
Run Code Online (Sandbox Code Playgroud)
在 C++17 中,您可以创建变量inline以避免必须在 a 中提供其定义.cpp:
namespace TRIALS {
inline thread_local int a = -1;
}
Run Code Online (Sandbox Code Playgroud)