Qt QFuture Memoryleak

Qt QFuture Memoryleak,qt,memory-leaks,parallel-processing,qfuture,Qt,Memory Leaks,Parallel Processing,Qfuture,我想并行化一个函数,但有一个问题,几个小时后我的内存过载 这个测试程序计算出一些简单的东西,目前为止还有效。只有内存使用量在不断增加 QT项目文件: QT -= gui QT += concurrent widgets CONFIG += c++11 console CONFIG -= app_bundle DEFINES += QT_DEPRECATED_WARNINGS SOURCES += main.cpp QT程序文件: #include <QCoreApplication>

我想并行化一个函数,但有一个问题,几个小时后我的内存过载

这个测试程序计算出一些简单的东西,目前为止还有效。只有内存使用量在不断增加

QT项目文件:

QT -= gui
QT += concurrent widgets
CONFIG += c++11 console
CONFIG -= app_bundle
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
QT程序文件:

#include <QCoreApplication>
#include <qdebug.h>
#include <qtconcurrentrun.h>

double parallel_function(int instance){
    return (double)(instance)*10.0;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int nr_of_threads = 8;
    double result_sum,temp_var;
    for(qint32 i = 0; i<100000000; i++){
      QFuture<double> * future = new QFuture<double>[nr_of_threads];

      for(int thread = 0; thread < nr_of_threads; thread++){
        future[thread] = QtConcurrent::run(parallel_function,thread);
      }
      for(int thread = 0; thread < nr_of_threads; thread++){
        future[thread].waitForFinished();
        temp_var = future[thread].result();
        qDebug()<<"result: " << temp_var;
        result_sum += temp_var;
      }
  }

  qDebug()<<"total: "<<result_sum;
  return a.exec();
}
#包括
#包括
#包括
双并行_函数(int实例){
返回(双倍)(实例)*10.0;
}
int main(int argc,char*argv[])
{
qcorea应用程序(argc、argv);
内螺纹数=8;
双结果总和,临时变量;

对于(qint32 i=0;i您存在内存泄漏,因为未删除
future
数组。在外部for循环的末尾添加
delete[]future

for(qint32 i = 0; i<100000000; i++)
{
   QFuture<double> * future = new QFuture<double>[nr_of_threads];

   for(int thread = 0; thread < nr_of_threads; thread++){
     future[thread] = QtConcurrent::run(parallel_function,thread);
   }
   for(int thread = 0; thread < nr_of_threads; thread++){
      future[thread].waitForFinished();
      temp_var = future[thread].result();
      qDebug()<<"result: " << temp_var;
      result_sum += temp_var;
   }

   delete[] future; // <--
}

for(qint32 i=0;i内存泄漏,因为未删除
future
数组。在外部for循环末尾添加
delete[]future

for(qint32 i = 0; i<100000000; i++)
{
   QFuture<double> * future = new QFuture<double>[nr_of_threads];

   for(int thread = 0; thread < nr_of_threads; thread++){
     future[thread] = QtConcurrent::run(parallel_function,thread);
   }
   for(int thread = 0; thread < nr_of_threads; thread++){
      future[thread].waitForFinished();
      temp_var = future[thread].result();
      qDebug()<<"result: " << temp_var;
      result_sum += temp_var;
   }

   delete[] future; // <--
}

用于(qint32 i=0;i这可能看起来是这样的-注意每件事都可以简单得多!你死定要做手动内存管理:为什么?首先,
QFuture
是一个值。你可以非常有效地将它存储在任何向量容器中,为你管理内存。你可以使用range for.Etc迭代这样的容器

QT = concurrent   # dependencies are automatic, you don't use widgets
CONFIG += c++14 console
CONFIG -= app_bundle
SOURCES = main.cpp
尽管该示例是合成的,而且
map\u函数非常简单,但还是值得考虑如何以最高效和最具表现力的方式进行操作。您的算法是典型的map reduce操作,
blockingMappedReduce
的开销只有手动完成所有工作的一半

首先,让我们重写C++中的原始问题,而不是一些C语言的例子。
// https://github.com/KubaO/stackoverflown/tree/master/questions/future-ranges-49107082
/* QtConcurrent will include QtCore as well */
#include <QtConcurrent>
#include <algorithm>
#include <iterator>

using result_type = double;

static result_type map_function(int instance){
   return instance * result_type(10);
}

static void sum_modifier(result_type &result, result_type value) {
   result += value;
}

static result_type sum_function(result_type result, result_type value) {
   return result + value;
}

result_type sum_approach1(int const N) {
   QVector<QFuture<result_type>> futures(N);
   int id = 0;
   for (auto &future : futures)
      future = QtConcurrent::run(map_function, id++);
   return std::accumulate(futures.cbegin(), futures.cend(), result_type{}, sum_function);
}
我们还可以尝试使用随机访问迭代器:

using num_r_iterator = num_iterator<std::random_access_iterator_tag>;

result_type sum_approach5(int const N) {
   return QtConcurrent::blockingMappedReduced(num_r_iterator{0}, num_r_iterator{N},
                                              map_function, sum_modifier);
}

请注意,在随机iterable序列上使用map reduce比使用
QtConcurrent::run
的开销低3个数量级以上,比非随机iterable解决方案快2个数量级。

这可能看起来是这样的-请注意,一切都可以简单得多!您已经下定决心要做手动备忘了ry管理:为什么?首先,
QFuture
是一个值。您可以将它非常高效地存储在任何向量容器中,该容器将为您管理内存。您可以使用range for.Etc迭代这样的容器

QT = concurrent   # dependencies are automatic, you don't use widgets
CONFIG += c++14 console
CONFIG -= app_bundle
SOURCES = main.cpp
尽管该示例是合成的,而且
map\u函数非常简单,但还是值得考虑如何以最高效和最具表现力的方式进行操作。您的算法是典型的map reduce操作,
blockingMappedReduce
的开销只有手动完成所有工作的一半

首先,让我们重写C++中的原始问题,而不是一些C语言的例子。
// https://github.com/KubaO/stackoverflown/tree/master/questions/future-ranges-49107082
/* QtConcurrent will include QtCore as well */
#include <QtConcurrent>
#include <algorithm>
#include <iterator>

using result_type = double;

static result_type map_function(int instance){
   return instance * result_type(10);
}

static void sum_modifier(result_type &result, result_type value) {
   result += value;
}

static result_type sum_function(result_type result, result_type value) {
   return result + value;
}

result_type sum_approach1(int const N) {
   QVector<QFuture<result_type>> futures(N);
   int id = 0;
   for (auto &future : futures)
      future = QtConcurrent::run(map_function, id++);
   return std::accumulate(futures.cbegin(), futures.cend(), result_type{}, sum_function);
}
我们还可以尝试使用随机访问迭代器:

using num_r_iterator = num_iterator<std::random_access_iterator_tag>;

result_type sum_approach5(int const N) {
   return QtConcurrent::blockingMappedReduced(num_r_iterator{0}, num_r_iterator{N},
                                              map_function, sum_modifier);
}

如何使用Map Reduce对随机迭代序列的开销比使用<代码> QtReal:To运行3个数量级::运行,比非随机迭代解决方案快2个数量级。< /强> < / P>没有人应该编写使用生鲜新/删除的C++代码……这是非常糟糕的建议。避免内存泄漏的方法是不要试图使手动内存管理正确。避免内存泄漏的方法是编写代码,其中内存泄漏是不可能的。设计意味着编写C++,而不是C - C++ + -语法。任何人都不应该编写使用生鲜新/删除的C++代码……这是非常糟糕的建议。为了避免内存泄漏,不要试图更难获得手动内存管理。避免内存泄漏的方法是编写代码,其中内存泄漏是不可能的设计。这意味着编写C++,而不是C-USE-C++ + SythAcL。写得很好的答案。写得很好的答案。
sum: 4999995000000.000000 took 0.015778 ms/item
sum: 4999995000000.000000 took 0.003631 ms/item
sum: 4999995000000.000000 took 0.003610 ms/item
sum: 4999995000000.000000 took 0.005414 ms/item
sum: 4999995000000.000000 took 0.000011 ms/item
sum: 4999995000000.000000 took 0.000008 ms/item