Why may thread_local
不适用于非静态数据成员?接受的答案这个问题 https://stackoverflow.com/questions/10999131/can-you-use-thread-local-variables-inside-a-class-or-structure说:“将非静态结构或类成员设置为线程本地是没有意义的。”老实说,我看到很多让非静态数据成员成为线程本地的充分理由。
假设我们有某种ComputeEngine
具有成员函数computeSomething
连续调用多次。成员函数内部的一些工作可以并行完成。为此,每个线程都需要某种ComputeHelper
例如,它提供辅助数据结构。所以我们真正想要的是以下内容:
class ComputeEngine {
public:
int computeSomething(Args args) {
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < MAX; ++i) {
// ...
helper.xxx();
// ...
}
return sum;
}
private:
thread_local ComputeHelper helper;
};
不幸的是,这段代码无法编译。我们可以做的是:
class ComputeEngine {
public:
int computeSomething(Args args) {
int sum = 0;
#pragma omp parallel
{
ComputeHelper helper;
#pragma omp for reduction(+:sum)
for (int i = 0; i < MAX; ++i) {
// ...
helper.xxx();
// ...
}
}
return sum;
}
};
然而,这将构建和破坏ComputeHelper
连续调用之间computeSomething
。假设构建ComputeHelper
是昂贵的(例如,由于巨大向量的分配和初始化),我们可能想重用ComputeHelper
连续调用之间的间隔。这导致我采用以下样板方法:
class ComputeEngine {
struct ThreadLocalStorage {
ComputeHelper helper;
};
public:
int computeSomething(Args args) {
int sum = 0;
#pragma omp parallel
{
ComputeHelper &helper = tls[omp_get_thread_num()].helper;
#pragma omp for reduction(+:sum)
for (int i = 0; i < MAX; ++i) {
// ...
helper.xxx();
// ...
}
}
return sum;
}
private:
std::vector<ThreadLocalStorage> tls;
};
- Why may
thread_local
不适用于非静态数据成员?什么
这个限制背后的理由是什么?难道我没有给予一个好的
线程本地非静态数据成员完美的示例
感觉?
- 实现线程本地非静态的最佳实践是什么
数据成员?
至于为什么thread_local
不能应用于非静态数据成员,它会破坏此类成员的通常排序保证。也就是说,单个数据成员public/private/protected
组必须按照与类声明中相同的顺序在内存中布局。更不用说如果您在堆栈上分配一个类会发生什么——TLS 成员不会进入堆栈。
至于如何解决这个问题,我建议使用boost::thread_specific_ptr http://www.boost.org/doc/libs/release/doc/html/thread/thread_local_storage.html。您可以将其中之一放入您的类中并获得您想要的行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)