这是我第一次使用线程,而我正在使用boost。 情况是我有一大堆3d多边形网格,我为此构建一个八叉树(每个网格一棵树)。 我想并行执行构建过程,并立即转到openGL显示循环 - 无需等待构建完成。 (该对象在其octre完成之前不会显示任何内容)。
我使用boost :: scoped_ptr :: reset()将八叉树数据附加到我的对象。 我可以将reset()方法视为线程执行中的原子操作吗?如果不是我应该照顾什么?
以下是描述我正在做什么的伪代码。 实际代码按预期工作,但偶尔会遇到崩溃(可能与其他事件有关。)
class BigData
{
private:
boost::scoped_ptr<float*> p_data_;
public:
void Compute() // this will run in threads
{
float* p_temp = new float [1000];
DoComputation(p_temp);
p_data_.reset(p_temp); // atomic ?
}
void operator()() {Compute();}
void Display() // do nothing if p_data_ is not ready
{
if(p_data_)
DoDisplay();
}
}
int main()
{
std::vector<BigData> objects_arr(1000);
// run Compute() in threads
for(int i=0; i<objects_arr.size(); ++i)
boost::thread comp_thread( objects_arr[i] );
// immediately go to display
while(true)
{
for(int i=0; i<objects_arr.size(); ++i)
objects_arr[i].Display();
}
}
答案 0 :(得分:1)
不。对于boost :: scoped_ptr来说,这实际上不是一个问题,而是一般的指针赋值问题。
答案 1 :(得分:0)
像scoped_array,scoped_ptr,shared_ptr这样的类只是RIIA模式的不同实现,并且不是线程安全的。所以,如果你想在多线程上下文中使用那些可以发生数据竞争的类,你必须自己使用同步原语保护这些变量
在定义scoped_ptr时,您不必提及它将存储ptr。它是设计的,所以我们可以写:
boost::scoped_ptr<float> p_data_;
并查看您的代码我认为您想写:
void Compute() // this will run in threads
{
boost::scoped_array<float> p_data(new float [1000]);
DoComputation(p_data.get());
// no need to call reset ...
}
我用scoped_array替换scoped_array,因为如果你用new []分配一些东西,你必须用delete []和scoped_array来释放它!
我们也可以删除重置调用,因为scoped_ ..类提供的RIIA模式通过设计提供了这种行为。当标识符超出范围时,资源被释放。