我正在尝试使用boost::thread_group
来管理我的主题。设计是这样的,线程组中的每个线程都会调用struct A
的一系列仿函数。
伪代码:
struct A {
int n;
vector p;
void operator()() {
for(number_of_steps) // Do computations involving members n, p, x and y.
}
private:
float x;
vector y;
};
struct parallel_A : boost::thread_group {
parallel_A(const A* a) : m_a(a) {
for(number_of_cpu) {
create_thread(inner_struct(this));
}
}
void run() {
(*m_a)();
}
private:
struct inner_struct {
parallel_A* a;
inner_struct(parallel_A* _a) : a(_a) {}
void operator()() {
a->run();
}
}
const A* m_a;
}
我的问题是:
数据变量n
,p
,x
和y
以及对象A
中的计算是否交错< / em>由线程?
如果我们通过为每个CPU调用仿函数A
来进一步调用,例如1个线程用于1个CPU并且每个线程4个调用仿函数A
来做计算,A
的变量状态和计算的行为是什么?
答案 0 :(得分:0)
基于代码:
for(number_of_cpu) {
create_thread(inner_struct(this));
this
指针的相同值将传递给所有线程,因此线程将共享相同的n
,p
,x
和{{1}数据变量。 y
的计算在任何情况下都会交错(除了可能用于关键部分)但现在由于计算共享相同的数据变量,因此很可能一次计算将使用意味着另一次计算的中间值导致数据损坏
我建议通过定义A
个对象的数组和/或使用boost::thread_specific_ptr等正式机制来使用某种形式的线程局部存储。
如果未使用线程本地存储(即上面的代码按原样保留),添加更多的仿函数A
将会增加数据损坏的可能性。
如果使用线程本地存储,由于指令仍然在一个线程内顺序执行,在每个线程中再添加4个仿函数A
将意味着计算将花费大约5倍的时间。这假设在每个线程中没有创建子线程来处理其他调用。