我有一个类('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)是对我如何设法使线程工作的参考 - 以及为什么它是唯一的解决方案。
答案 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;
}