[英]C++ multiple threads and vectors
I tried various implementations of the following algorithm but always ended up with a crash after a while the program runs... 我尝试了以下算法的各种实现,但始终会在程序运行一段时间后崩溃。
I have a base object 我有一个基础对象
class Element
{
public:
int a;
float p;
Element(int _a, float _p=1.0): a(_a), p(_p){};
};
of which I create a vector and include in a Buffer object. 我创建了一个向量并将其包含在Buffer对象中。
class Buffer
{
public:
Buffer(){};
vector<Element> raw;
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
for(i=1; i<9999999; i++)
t = 9./i;
}
};
void clear() // ERASE BOTH BUFFERS
{
raw.clear();
optimised.clear();
}
};
I have a declaration of a single Buffer object - responsible for capturing the current data stream - and a vector of Buffer objects - behaving like a history/queue of the previously created buffers. 我有一个单个Buffer对象的声明-负责捕获当前数据流-以及一个Buffer对象的向量-行为类似于先前创建的缓冲区的历史记录/队列。
Buffer buffer;
vector<Buffer> queue;
The main thread is responsible of filling the buffer object and - once a series is complete - submit the buffer into the queue. 主线程负责填充缓冲区对象,并且-一旦完成一系列操作,就将缓冲区提交到队列中。 As soon as a new buffer is added to the queue a Compute() function is called on a separate thread to analyse the recently submitted data.
一旦将新缓冲区添加到队列中,就会在单独的线程上调用Compute()函数以分析最近提交的数据。
//ADD THE CURRENT BUFFER TO THE QUEUE
queue.push_back(buffer);
//RUN 'COMPUTE' IN PARALLEL/BACKGROUND ON THE LAST SUBMITTED BUFFER
std::thread t(&Buffer::compute, &queue.back());
t.detach();
//CLEAR THE BUFFER, READY FOR A NEW SERIES
buffer.clear();
The program complies fine and launches but it crashes during execution (sometimes after just one buffer is submitted, sometimes after a few... it generally 'works for longer' if there is only one buffer at a time in the queue). 该程序可以正常运行并启动,但是会在执行过程中崩溃 (有时仅提交一个缓冲区,有时在提交几个缓冲区之后……如果队列中一次只有一个缓冲区,通常“可以工作更长的时间”)。
Do I need to use mutex locks in this situation ? 在这种情况下是否需要使用互斥锁? If so, where ?
如果是这样,在哪里?
Do you have any suggestion on how to optimise the collection of the data (fill the 'buffer' object and submit it into the queue) - I think AddElement() is a bit unnecessarily expensive ? 您是否对如何优化数据收集(填充“缓冲区”对象并将其提交到队列中)有任何建议-我认为AddElement()有点不必要地昂贵?
ANY HELP APPRECIATED! 任何帮助!
Thanks 谢谢
The problem is with &queue[last]
. 问题出在
&queue[last]
。 That gives you a pointer to where the vector currently stores the buffer. 这为您提供了指向向量当前存储缓冲区位置的指针。 If vector reallocates (
push_back
can do that), then the pointer is invalid. 如果vector重新分配(
push_back
可以这样做),则指针无效。
There are a few solutions to this: 有一些解决方案:
queue
vector. queue
向量中。 Something like vector<unique_ptr<Buffer>> queue
will work (and makes sure you don't accidentally leak the memory). vector<unique_ptr<Buffer>> queue
将起作用(并确保您不会意外泄漏内存)。 list
and deque
will work. list
和deque
将起作用。 resize(x)
initially, and then keep track of the last yourself. resize(x)
,然后自己跟踪最后一个。 Update: Add a code sample. 更新:添加代码示例。 This compiles and runs fine on Coliru ( http://coliru.stacked-crooked.com/ )
这可以在Coliru( http://coliru.stacked-crooked.com/ )上编译并正常运行
#include <memory>
#include <vector>
#include <iostream>
class Buffer {};
int main()
{
std::unique_ptr<Buffer> buffer {new Buffer()};
std::vector<std::unique_ptr<Buffer>> queue;
for (int i = 0; i < 10; i++) {
buffer.reset(new Buffer());
// Do things to buffer;
queue.push_back(move(buffer));
}
std::cout << queue.size() << std::endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.