从线程移回()数据

时间:2013-12-03 18:54:47

标签: c++ multithreading move shared-memory unique-ptr

我有一个类('Buffer'),其中包含<矢量> data和analyze()函数对数据进行一些计算('raw'和'optimized')。

class Buffer
    {
    public:
        Buffer(){};

        vector<Element> raw;       
        vector<Element> optimised; // DATA CALCULATED BASED ON RAW

        [...]

        void analyze()  // COMPUTE THE OPTIMISED BUFFER
        {
            for(std::vector<Element>::iterator it = raw.begin(); it != raw.end(); ++it) 
            {
                optimised.push_back(Element(it->a,it->p));
                // DO SOME COMPUTATIONALLY INTENSIVE CALCULATIONS
                for(i=1; i<9999999; i++)
                    t = 9./i;
            }
        };
    };

因为我需要创建一系列上面的'Buffer'对象并保持交互式帧率,所以我将每个缓冲区对象的analyze()函数运行到一个单独的线程上。 我找到的唯一可行的解​​决方案是使用unique_ptr来保存我的缓冲区对象集合

std::unique_ptr<dynamica::Buffer> buffer; //TEMPORARY COLLECTOR
std::vector<std::unique_ptr<dynamica::Buffer>> queue; //COLLECTION OF ALL PREVIOUS BUFFERS

因此在将每个对象传递给相应的线程时使用move()。

queue.push_back(move(buffer));
//RUN 'ANALYZE' IN PARALLEL IN BACKGROUND
std::thread t(&Buffer::analyze, move(queue.back()));
t.detach();

我的问题(我怀疑)是在我将我的对象移动到一个新线程进行analyze()计算之后,我无法分析访问其中的变量和方法(一旦并行线程已完成)来自主线程。

//from the main thread, once I know the parallel thread doing analyze() has finished
queue[0]->someFunction() // CRASH! ERROR! BOOM!

PS:这里(C++ multiple threads and vectors)是对我如何设法使线程工作的参考 - 以及为什么它是唯一的解决方案。

1 个答案:

答案 0 :(得分:0)

这不是一个真正的线程问题。这是对移动语义的误解我认为,你已经将队列交给了分离的线程,因此不再拥有它。

编辑(示例代码):

#include <vector>
#include <iostream>
#include <memory>
#include <thread>

class Element
{
public:
    int a;
    float p;
    Element(int _a, float _p=1.0): a(_a), p(_p){};
};

class Buffer
{
public:
    Buffer(){};

    std::vector<Element> raw;       
    std::vector<Element> optimised; // DATA CALCULATED BASED ON RAW

    void addElement(int _a,float _p=1.0) // FILL THE RAW BUFFER
    {
        raw.push_back(Element(_a,_p));
    }

    void compute()  // COMPUTE THE OPTIMISED BUFFER
    {
        float t;
        int i;
        for(std::vector<Element>::iterator it = raw.begin(); it != raw.end(); ++it) 
        {
            optimised.push_back(Element(it->a,it->p));
            // DO SOME COMPUTATIONALLY INTENSIVE CALCULATIONS
            std::cout << "Performing calculations..." << std::endl;
            for(i=1; i<9999999; i++)
                t = 9./i;
        }
    };

    void clear() // ERASE BOTH BUFFERS
    {
        raw.clear();
        optimised.clear();
    }

    const std::pair<std::vector<Element>::const_iterator, std::vector<Element>::const_iterator> someFunction()
    {
        return std::make_pair<std::vector<Element>::const_iterator, std::vector<Element>::const_iterator>(begin(optimised), end(optimised));
    }

    ~Buffer() { clear(); }
};


int _tmain(int argc, _TCHAR* argv[])
{
Buffer origin;
auto buffer = std::make_shared<Buffer *>(&origin);
std::vector<decltype(buffer)> queue;

for(int i = 0; i < 10; i++ )
    (*buffer)->addElement(i);

queue.push_back(buffer);

std::thread t(&Buffer::compute, *queue.back());

t.join(); // wait for results

auto result = (*queue.back())->someFunction();

for( auto ele = result.first; ele != result.second; ele++   )
{
    std::cout << (*ele).a << std::endl;
}

return 0;
}