I am using QThreadPool to run a worker that has function to create then clear huge QVector and write huge size of file. However, every time one worker reach that lines (QVector::clear/QFile::close) all the threads got freeze and will continue when it is finished.
Is someone has any suggestion to overcome this situation ? To have other threads still capable to run normal when in one of the worker run those two functions. For QFile::close, I tried to use QFile::flush in my iteration instead of close() in the end of iterations, but it's not helping the performance.
This is the codes when the thread getting slower when clearing the vector
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_start_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "worker.h"
#include <QDebug>
#include <QSharedPointer>
#include <QThread>
#include <QThreadPool>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
on_start_pushButton_clicked();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_start_pushButton_clicked()
{
int numProcess = 20;
int numTraces = 10000;
int numSamps = 8680;
qDebug() << "main" << QThread::currentThread();
QThreadPool *pool = QThreadPool::globalInstance();
for (int i=0; i<numProcess; i++) {
worker *w= new worker;
w->setAutoDelete(true);
w->setData(i+1, numTraces, numSamps);
pool->start(w);
}
}
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="start_pushButton">
<property name="geometry">
<rect>
<x>240</x>
<y>50</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
worker.h
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include <QRunnable>
#include <QThread>
class worker : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit worker(QObject *parent = nullptr) : QObject(parent), QRunnable () {}
~worker() {}
void setData(int id, int numTraces, int numSamps);
void run();
signals:
public slots:
private:
void clearVector();
int id, numTraces, numSamps;
};
#endif // WORKER_H
worker.cpp
#include "worker.h"
#include <QCoreApplication>
#include <QDebug>
#include <QVector>
void worker::setData(int id1, int numTraces, int numSamps)
{
this->id = id1;
this->numTraces = numTraces;
this->numSamps = numSamps;
qDebug() << "setData" << id << numTraces << numSamps;
}
void worker::run()
{
clearVector();
qDebug() << "pool finished" << id << numTraces << numSamps << QThread::currentThread();
}
void worker::clearVector()
{
QVector<QVector<float>> traces1, traces2;
float progressWaypoint = 0.01f*numTraces;
int progressPos = 0;
for (int i=0; i<numTraces; i++) {
QVector<float> trace1, trace2;
for (int j=0; j<numSamps; j++) {
trace1.append(float(j));
trace2.append(float(numSamps - j));
}
traces1.append(trace1);
traces2.append(trace2);
if (numTraces <= 100) {
QCoreApplication::processEvents();
}
else {
if (i + 1 >= round(progressWaypoint*progressPos)) {
QCoreApplication::processEvents();
qDebug() << id << QThread::currentThread() << progressPos;
progressPos++;
}
}
}
traces1.clear();
traces2.clear();
}