簡體   English   中英

Memory 泄漏 C++ 穿線

[英]Memory leakage C++ threading

我有一個問題,可能是 memory 在 C++ 線程中泄漏。 我收到代碼為 11 的運行時錯誤。我正在編寫優化算法,旨在優化 2D 反應器的參數。 它生成重整 function 的實例,創建 Reformer 對象。 重整器有 2 個不同的參數,可以在單個重整器中局部不同,並從主 function 傳遞給重整 function。為了具體說明,每個重整器被分成指定數量的區域(每個重整器中的尺寸和位置相同),每個區域可以有不同的參數。 因此,2 個向量中每個向量的大小都等於 [改革者數量] * [區域數量]。 然后,改造 function 創建 Segment 對象,其數量等於區域數。

我假設這里的問題是線程試圖同時訪問同一個向量,我真的很感激這個問題的解決方案。

評論:

  1. 如果我更改 main.cpp 以用普通循環替換線程,則不會返回任何錯誤。
  2. 如果我在 set_segments 函數中注釋掉 setProp 方法,則不會返回任何錯誤(使用線程)。

這里強烈推薦線程,因為單個 Reformer 的計算時間很長,而且我可以訪問多核計算單元。

為了澄清,我將用一個最小的可重現示例來解釋所有內容:

輸入.h

#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
int reactor_no = 2;    // number of reformers
int zones_X = 5;       // number of zones in a single reformer, X direction
int zones_Y = 2;       // number of zones in a single reformer, Y direction
double dim_X = 0.5;    // reactor's length    
double dim_Y = 0.2;    // reactor's height
double wall_t = 0.1;   // thickness of the reactor wall
size_t zones = zones_X * zones_Y;

改革者.h:

#include "input.h"
class Reformer {
public:
    Reformer() {}
    Reformer(const double& L, const double& Y, const double& wall_t, 
                        const int& zones_X = 1, const int& zones_Y = 1) {
        length_ = L;
        height_ = Y;
        zonesX_ = zones_X;
        zonesY_ = zones_Y;
        wall_thickness_ = wall_t;   

        dx_ = length_ / static_cast<double> (zonesX_);
        dr_ = height_ / static_cast<double> (zonesY_);
    }

private:
    double wall_thickness_;         // wall thickness (m)
    double length_;                 // recactor length (m)
    double height_;                 // reactor height (m) (excluding wall thickness)
    int zonesX_;                    // number of segments in the X direction
    int zonesY_;                    // number of segments in the Y direction 
    double dx_;                     // segment width    (m)
    double dr_;                     // segment height (m)
}

段.h:

#include "input.h"
class Segment{
public:
    Segment() : Segment(0, 0) {}

    Segment(int i, int j) {
        i_ = i;
        j_ = j;
    }

    void setXR(const double& dx, const double& dr, const int& SL, const int& SR) {
        x0_ = i_ * dx;
        x1_ = x0_ + dx;

        r0_ = j_ * dr;
        r1_ = r0_ + dr;

        if (i_ == SL - 1) {
            x1_ = length;
        }

        if (j_ == SR - 1) {
            r1_ = radius;
        }   
    }

    void setWall() {
        x0_ = 0;
        x1_ = length;

        r0_ = radius;
        r1_ = radius + wall_t;
    }

    void setProp(const double& por, const double& por_s, const bool& cat) {
        porosity_ = por;
        catalyst_ = cat;
    }
private:
    size_t i_;          //segment column no.
    size_t j_;          //segment row no.

    double x0_;         //beginning of segment - x coordinate (m)
    double x1_;         //ending of segment - x coordinate (m)
    double r0_;         //beginning of segment - r coordinate (m)
    double r1_;         //ending of segment - r coordinate (m)

    int catalyst_;      //1 - catalytic, 0 - non-catalytic
    double porosity_;   //porosity (-)

};

主.cpp:

#include "input.h"
int main() {

    int zones = zones_X * zones_Y;

    size_t pop_size = reactor_no * zones;
    std::vector<int> cat;
    cat.reserve(pop_size);
    std::vector<double> porosity;
    porosity.reserve(pop_size);                // the values in the vectors are not important, therefore I will just fill them with 1s
    for (int i = 0; i < pop_size; i++) {
        cat[i] = 1;
        porosity[i] = 1.0;
    }

    std::vector<std::thread> Ref;
    Ref.reserve(reactor_no);
    for (k = 0; k < reactor_no; k++) {
        Ref.emplace_back(reforming, k, cat, porosity);
    }

    for (auto &X : Ref) { X.join(); }
}

改革.cpp:

    #include "input.h"

void reforming(const int m, const std::vector<int>& cat_check, const std::vector<double>& por) {                                           
    Reformer reactor(length, radius, wall_t, zonesX, zonesY);

    std::vector<Segment> seg;     // vector holding segment objects                                                                  
    seg.reserve(zones);

    set_segments(seg, reactor, zones, m, por, por_s, cat_check);

}

set_segments function:

#include "input.h"
void set_segments(std::vector<Segment> &seg, Reformer &reac, const int m, 
                     const std::vector<double> &por, const std::vector<int> &check) {
    int i, j, k, n;

    double dx = dim_X / static_cast<double> (zones_X);
    double dy = dim_Y / static_cast<double> (zones_Y);

    std::vector<Segment*> ptr_seg;
    ptr_seg.reserve(zones);

    k = 0;
    for (i = 0; i < zones_X; i++) {
        for (j = 0; j < zones_Y; j++) {
            n = m * zones + (i * zones_Y + j);
            seg.emplace_back(Segment(i, j));
            seg[k].setProp(por[n], check[n]);
            seg[k].setXR(dx, dy, zones_X, zones_Y);
            k++;
        }
    }

}  

將 std::ref() 添加到重整的 function 調用參數中解決了這個問題。

for (k = 0; k < spec_max; k++) {
        Ref.emplace_back(reforming, k, std::ref(cat), std::ref(porosity));
}

暫無
暫無

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

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