OpenCV多线程泄漏内存

时间:2018-08-22 06:01:37

标签: c++ multithreading opencv

我正在尝试使用OpenCV(C ++)中的MergeMertens暴露堆栈和多个线程来加速它。它确实可以加快速度,但是每次调用mergeExposuresInThread()之后,内存都会不断增加。

现在它正在执行4个线程,然后从下一个4开始。 它会根据基本字符串合并来自已知文件名的5个不同帧(很好地猜测)。

这是怎么了?我觉得我要释放所有已分配的对象,并且已经在stackoverflow上阅读了有关此内容的大多数文章。

在执行mergeExposuresInThread(...)大约30-40次之后,应用程序被操作系统(Ubuntu 16.04)(牺牲子级)杀死了

我使用top命令监视内存使用情况,并且它会随着时间的推移而上升(如执行mergeExposures(...)的次数更多),并在执行后下降,但总体趋势是上升,然后在顶部显示〜85%的内存使用情况。

int HDRMaker::mergeExposuresInThread(std::vector<std::string> files)
{

    const int maxThreads = 4;
    int threadsActive = 0;

    if (hdrThreads.size() != maxThreads)
    {
        hdrThreads.resize(files.size());

    }
    // Init status
    hdrThreadsStatus.resize(files.size());
    for (int i = 0; i < hdrThreadsStatus.size(); i++)
    {
        hdrThreadsStatus[i] = 0;
    }

    if (resultImgs.size() != 24)
    {
        resultImgs.resize(24);
    }

    printf("mergeExposuresInThread - start\n");

    int nextImg = 0;

    bool shallWeRun = true;
    while(shallWeRun)
    {

        if (threadsActive <= maxThreads)
        {

            const int pos = nextImg;
            const std::string fname = std::string(files[pos]);
            nextImg++;
            threadsActive++;
            hdrThreadsStatus[pos] = 1;

            hdrThreads[pos]=(new std::thread([this, pos, fname] {
                printf("%d %d %s\n", __LINE__, pos, fname.c_str());
                Mat fusionResult;
                std::string hdrBase = std::string(fname);
                ReplaceStringInPlace(hdrBase, "color", "color_exp");
                printf("mergeExp:%s\n", hdrBase.c_str());
                ReplaceStringInPlace(hdrBase, ".png", "_");

                std::vector<cv::Mat> fusionFrames;
                for (int i = 0; i < 5; i++)
                {
                    std::string expName = std::string(hdrBase + std::to_string(i) + ".png");
                    // printf("%s\n", expName.c_str());
                    cv::Mat exp = imread(hdrBase + std::to_string(i) + ".png");
                    fusionFrames.push_back(exp);
                    exp.release();
                }

                Ptr<MergeMertens> mergeMertens = createMergeMertens();
                mergeMertens->process(fusionFrames, fusionResult);
                cv::Mat rgbResult;
                fusionResult = fusionResult*255;
                fusionResult.convertTo(rgbResult, CV_8UC3);

                accessVectorMutex.lock();
                resultImgs[pos] = rgbResult;
                accessVectorMutex.unlock();




                imwrite(fname, rgbResult); //debug

                printf("Collage ProcessHDRandSaveFile %s end\n", hdrBase.c_str());

                for (int i = 0; i < 5; i++)
                {
                    fusionFrames[i].release();
                }


                fusionResult.release();
                rgbResult.release();
                mergeMertens.release();

            }));
        }


        if (threadsActive >= maxThreads)
        {
            for (int t = 0; t < hdrThreads.size(); t++)
            {
                accessVectorStatus.lock();
                if (hdrThreadsStatus[t] == 1)
                {
                    accessVectorStatus.unlock();
                    if (hdrThreads[t]->joinable())
                    {
                        hdrThreads[t]->join();
                        delete hdrThreads[t];       
                        hdrThreads[t]=nullptr;
                        accessVectorStatus.lock();
                        hdrThreadsStatus[t] = 2;
                        threadsActive--;
                        accessVectorStatus.unlock();
                        printf("Thread:%d killed\n", t);
                        // break;
                    }
                }
                else
                {
                    accessVectorStatus.unlock();
                }
            }
        }


        bool foundFalse = false;
        for (int i = 0; i < hdrThreadsStatus.size(); i++)
        {
            if (hdrThreadsStatus[i] != 2)
            {
                foundFalse = true;
                break;
            }
        }
        if (foundFalse)
        {
            shallWeRun = true;
        }
        else
        {
            printf("All thread done exit\n");
            shallWeRun = false;
            break;
        }
    }

    for (int t = 0; t < hdrThreads.size(); t++)
    {
        accessVectorStatus.lock();
        if (hdrThreadsStatus[t] == 1)
        {
            accessVectorStatus.unlock();
            if (hdrThreads[t]->joinable())
            {
                hdrThreads[t]->join();
                delete hdrThreads[t];       
                hdrThreads[t]=nullptr;
                accessVectorStatus.lock();
                hdrThreadsStatus[t] = 2;
                threadsActive--;
                accessVectorStatus.unlock();
                printf("Thread:%d killed\n", t);
                break;
            }
        }
        else
        {
            accessVectorStatus.unlock();
        }
    }


    printf("mergeExposuresInThread - end\n");
    return 1;

}

void ReplaceStringInPlace(std::string& subject, const std::string& search,
                          const std::string& replace)
{
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}

标题

int mergeExposuresInThread(std::vector<std::string> files);
std::mutex accessVectorMutex;
std::mutex accessVectorStatus;
std::vector<std::thread*> hdrThreads;
std::vector<int> hdrThreadsStatus;
std::vector<cv::Mat> resultImgs;

通话代码

mergeExposuresInThread(filesAsStrings); // A list of 24 files
// Do other things (this does not leak without mergeExposuresInThread(...)
for (int i = 0; i < resultImgs.size(); i++)
{
    resultImgs[i].release();
}

0 个答案:

没有答案