gpt4 book ai didi

c++ - thread_local 变量在线程内不一致

转载 作者:行者123 更新时间:2023-12-03 02:37:40 27 4
gpt4 key购买 nike

我在文件 tracker.hpp 中有一个变量:

namespace TRIALS
{
static thread_local int a = -1;
}

我在 ema.hpp/ema.cpp 文件中有另一个名为 EMP 的类

namespace Algo
{
class EMP
{
public:
void Sample();
};
}
namespace Algo
{
void EMP::Sample()
{
std::cout << "model " << std::this_thread::get_id() << " " << &TRIALS::a << " " << TRIALS::a << std::endl;
}
}

然后我的主文件


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;
}

我只是运行一个线程进行调试,但这是输出:

0x7f9540b621d8

main 140279012532800 0x7f9540b621d8 -1(如预期)

型号 140278985606912 0x7f953f1b469c -1(这不应该是0吗?)

worker 140278985606912 0x7f953f1b4698 0(如预期)

main 140279012532800 0x7f9540b621d8 -1(如预期)

我的印象是每个线程都有它自己的 TRIALS::a 本地拷贝。模型中的 a 正确地递增,但是当它从同一线程中的函数返回时,该值仍然为 0。我正在打印线程 id 和 a 的地址以进行良好的测量,我发现实际上有 3 个不同的值尽管只有两个线程,但 TRIALS::a 的版本。

作为一个额外的问题,static thread_local int athread_local int a 之间有什么区别?

最佳答案

在您的示例中,static 使 thread_local 对象使用内部链接,以便每个翻译单元(.cpp 文件)都有自己的变量拷贝。

参见storage class specifiers详情:

The thread_local keyword is only allowed for objects declared at namespace scope, objects declared at block scope, and static data members. It indicates that the object has thread storage duration. It can be combined with static or extern to specify internal or external linkage (except for static data members which always have external linkage), respectively, but that additional static doesn't affect the storage duration.

即您可能希望删除该 static 关键字,以便在整个应用程序中只有该对象的一份拷贝。在头文件中执行:

namespace TRIALS {
extern thread_local int a;
}

.cpp 之一中:

thread_local int TRIALS::a = -1;

在 C++17 中,您可以使变量内联以避免必须在 .cpp 中提供其定义:

namespace TRIALS {
inline thread_local int a = -1;
}

关于c++ - thread_local 变量在线程内不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58270118/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com