boost threads - scoped_ptr :: reset()是一个原子操作吗?

时间:2014-02-27 21:16:24

标签: c++ boost-thread

这是我第一次使用线程,而我正在使用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();
    }

}

2 个答案:

答案 0 :(得分:1)

不。对于boost :: scoped_ptr来说,这实际上不是一个问题,而是一般的指针赋值问题。

Is pointer assignment atomic in C++?

答案 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模式通过设计提供了这种行为。当标识符超出范围时,资源被释放。