我正在尝试使用 boost::thread_group
来管理我的线程。设计是为了让线程组中的每个线程都调用结构 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
,被线程交错了吗?如果我们要更进一步,为每个 CPU 调用更多的仿函数
A
,例如 1 个线程对应 1 个 CPU,每个线程 4 次调用仿函数A
进行计算,根据变量的状态和A
的计算会有什么行为?
最佳答案
基于代码:
for(number_of_cpu) { create_thread(inner_struct(this));
this
指针的相同值将传递给所有线程,因此线程将共享相同的n
、p
、x
和y
数据变量。A
的计算在任何情况下都会交错(除了可能的关键部分)但现在由于计算共享相同的数据变量,很可能一个计算将使用用于另一个计算结果的中间值在数据损坏中。我建议通过定义
A
对象数组和/或使用正式机制(例如 boost::thread_specific_ptr)来使用某种形式的线程本地存储。 .如果不使用线程本地存储(即上面的代码保持原样),添加更多的仿函数
A
调用将增加数据损坏的可能性。如果使用线程本地存储,由于指令仍然在一个线程中顺序执行,在每个线程中添加 4 个仿函数
A
的调用将意味着计算将花费大约 5 倍的时间.这假设没有在每个线程中创建子线程来处理额外的调用。
关于c++ - 多线程中对象的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23560533/