簡體   English   中英

C ++多線程和向量

[英]C++ multiple threads and vectors

我嘗試了以下算法的各種實現,但始終會在程序運行一段時間后崩潰。

我有一個基礎對象

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

我創建了一個向量並將其包含在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();
        }
    };

我有一個單個Buffer對象的聲明-負責捕獲當前數據流-以及一個Buffer對象的向量-行為類似於先前創建的緩沖區的歷史記錄/隊列。

Buffer buffer;
vector<Buffer> queue;

主線程負責填充緩沖區對象,並且-一旦完成一系列操作,就將緩沖區提交到隊列中。 一旦將新緩沖區添加到隊列中,就會在單獨的線程上調用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();

該程序可以正常運行並啟動,但是會在執行過程中崩潰 (有時僅提交一個緩沖區,有時在提交幾個緩沖區之后……如果隊列中一次只有一個緩沖區,通常“可以工作更長的時間”)。

在這種情況下是否需要使用互斥鎖? 如果是這樣,在哪里?

您是否對如何優化數據收集(填充“緩沖區”對象並將其提交到隊列中)有任何建議-我認為AddElement()有點不必要地昂貴?

任何幫助!

謝謝

問題出在&queue[last] 這為您提供了指向向量當前存儲緩沖區位置的指針。 如果vector重新分配( 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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM