C ++的多个线程和载体(C++ multiple threads and vectors)

2019-10-19 02:14发布

我尝试了以下各种算法的实现,但总是结束了一个崩溃的程序运行一段时间后,...

我有一个基本对象

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

其中我创建矢量和包括在缓冲液中的对象。

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();
        }
    };

我有一个单一的缓冲器的对象的声明 - 负责捕捉当前的数据流 - 和Buffer对象的矢量 - 行为就像先前创建的缓冲器的历史/队列。

Buffer buffer;
vector<Buffer> queue;

主线程负责填充缓冲对象和 - 一旦一个系列齐全 - 提交缓存到队列中。 一旦一个新的缓冲区添加到队列中的计算()函数被调用一个单独的线程来分析最近提交的数据。

//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();

该方案规定罚款,并启动,但在执行过程中崩溃 (有时后有时只是一个缓冲提交后,几...它通常“工作更长的时间”如果只有一个缓冲在队列中的时间)。

我需要在这种情况下使用互斥锁? 如果是这样,在哪里?

你对如何优化数据的收集任何建议(补“缓冲”对象,并将其提交到队列中) -我认为的addElement()是有点贵不必要的?

任何帮助表示赞赏!

谢谢

Answer 1:

问题是与&queue[last] 。 这就给了你一个指针,它指向矢量当前存储缓冲区。 如果矢量重新分配( push_back可以做到这一点),然后将鼠标指针是无效的。

有这几个解决方案:

  • 存储指针在queue载体。 喜欢的东西vector<unique_ptr<Buffer>> queue将工作(并确保你不小心泄漏内存)。
  • 使用不会修改无效时无效指针一个数据结构。 listdeque会工作。
  • 确保载体不重新分配。 你可以做一个resize(x)开始,然后跟踪过去的自己。

更新:加入一个代码示例。 这将编译和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;
}


文章来源: C++ multiple threads and vectors