Add Code
This commit is contained in:
parent
0e95f69932
commit
47e3785ef6
99
QMain.cpp
Normal file
99
QMain.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#include "QMain.h"
|
||||||
|
|
||||||
|
QMain::QMain(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
qDebug() << QString("[ QMain ] QMain()");
|
||||||
|
|
||||||
|
qRegisterMetaType<QVector<int>>("QVector<int>");
|
||||||
|
|
||||||
|
w1 = new QWorker("Worker1");
|
||||||
|
w2 = new QWorker("Worker2");
|
||||||
|
w3 = new QWorker("Worker3");
|
||||||
|
|
||||||
|
currentTry = 0;
|
||||||
|
|
||||||
|
connect(w1, SIGNAL(workerFinished(QString, QVector<int>, int)), this, SLOT(workerSendResult(QString, QVector<int>, int)), Qt::DirectConnection);
|
||||||
|
connect(w2, SIGNAL(workerFinished(QString, QVector<int>, int)), this, SLOT(workerSendResult(QString, QVector<int>, int)), Qt::DirectConnection);
|
||||||
|
connect(w3, SIGNAL(workerFinished(QString, QVector<int>, int)), this, SLOT(workerSendResult(QString, QVector<int>, int)), Qt::DirectConnection);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(restart()), this, SLOT(beginSort()), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(startWorker(QVector<int>)), w1, SLOT(mergeSort(QVector<int>)));
|
||||||
|
connect(this, SIGNAL(startWorker(QVector<int>)), w2, SLOT(bubbleSort(QVector<int>)));
|
||||||
|
connect(this, SIGNAL(startWorker(QVector<int>)), w3, SLOT(quickSort(QVector<int>)));
|
||||||
|
|
||||||
|
stopPointers << &w1->stop << &w2->stop << &w3->stop;
|
||||||
|
|
||||||
|
w1->moveToThread(&t1); t1.start();
|
||||||
|
w2->moveToThread(&t2); t2.start();
|
||||||
|
w3->moveToThread(&t3); t3.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMain::~QMain()
|
||||||
|
{
|
||||||
|
qDebug() << QString("[ QMain ] ~QMain()");
|
||||||
|
t1.quit(); t1.wait(); delete w1; t1.deleteLater();
|
||||||
|
t2.quit(); t1.wait(); delete w2; t2.deleteLater();
|
||||||
|
t3.quit(); t1.wait(); delete w3; t3.deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> QMain::generateRandomVector()
|
||||||
|
{
|
||||||
|
QVector<int> data;
|
||||||
|
data.reserve(VECTOR_SIZE);
|
||||||
|
|
||||||
|
QRandomGenerator rnd;
|
||||||
|
|
||||||
|
qDebug() << QString("[ QMain ] Generating random vector...");
|
||||||
|
for (int i = 0; i < VECTOR_SIZE; ++i)
|
||||||
|
{
|
||||||
|
data.append(rnd.bounded(INT_MIN, INT_MAX));
|
||||||
|
}
|
||||||
|
qDebug() << QString("[ QMain ] Ready!");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMain::beginSort()
|
||||||
|
{
|
||||||
|
activeThreads = THREADS;
|
||||||
|
stop = false;
|
||||||
|
currentTry++;
|
||||||
|
|
||||||
|
qDebug() << QString("[ QMain ] ------------");
|
||||||
|
qDebug() << QString("[ QMain ] Try %1 of %2").arg(currentTry).arg(TRY_COUNT);
|
||||||
|
|
||||||
|
emit startWorker(generateRandomVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMain::workerSendResult(QString name, QVector<int> data, int msecs)
|
||||||
|
{
|
||||||
|
mutex.lock();
|
||||||
|
if (stop)
|
||||||
|
{
|
||||||
|
qDebug() << QString("[ %1 ] sort stopped.").arg(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
for (volatile bool *ptr : stopPointers) *ptr = true;
|
||||||
|
qDebug() << QString("[ %1 ] Finished with %2 msecs!").arg(name).arg(msecs);
|
||||||
|
qDebug() << QString("[ %1 ] Elements: %2").arg(name).arg(data.size());
|
||||||
|
// Do something with result
|
||||||
|
//for (int a : data)
|
||||||
|
// qDebug() << a;
|
||||||
|
}
|
||||||
|
workerStopped();
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMain::workerStopped()
|
||||||
|
{
|
||||||
|
if (!--activeThreads)
|
||||||
|
{
|
||||||
|
if (currentTry == TRY_COUNT)
|
||||||
|
emit closeProgram();
|
||||||
|
else
|
||||||
|
emit restart(); // Прямой вызов нельзя - иначе управление перейдет к "финишировавшему потоку"
|
||||||
|
}
|
||||||
|
}
|
49
QMain.h
Normal file
49
QMain.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef QMAIN_H
|
||||||
|
#define QMAIN_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "QWorker.h"
|
||||||
|
|
||||||
|
#define TRY_COUNT 10 // Количество повторов
|
||||||
|
#define VECTOR_SIZE 10000000 // Размер массива
|
||||||
|
|
||||||
|
#define THREADS 3 // Не менять!
|
||||||
|
|
||||||
|
class QMain : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QMain(QObject *parent = nullptr);
|
||||||
|
~QMain();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void closeProgram();
|
||||||
|
void startWorker(QVector<int> data);
|
||||||
|
void restart();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void beginSort();
|
||||||
|
void workerSendResult(QString name, QVector<int> data, int msecs);
|
||||||
|
void workerStopped();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QThread t1, t2, t3;
|
||||||
|
QWorker *w1, *w2, *w3;
|
||||||
|
QMutex mutex;
|
||||||
|
QVector<volatile bool*> stopPointers;
|
||||||
|
bool stop;
|
||||||
|
int activeThreads;
|
||||||
|
int currentTry;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<int> generateRandomVector();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMAIN_H
|
23
QThreadPerversions.pro
Normal file
23
QThreadPerversions.pro
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
QT -= gui
|
||||||
|
|
||||||
|
CONFIG += c++11 console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which as been marked deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
QMain.cpp \
|
||||||
|
QWorker.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
QMain.h \
|
||||||
|
QWorker.h
|
127
QWorker.cpp
Normal file
127
QWorker.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include "QWorker.h"
|
||||||
|
|
||||||
|
QWorker::QWorker(QString _name, QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
name = _name;
|
||||||
|
qDebug() << QString("[ %1 ] QWorker()").arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWorker::~QWorker()
|
||||||
|
{
|
||||||
|
qDebug() << QString("[ %1 ] ~QWorker()").arg(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWorker::mergeSort(QVector<int> _data)
|
||||||
|
{
|
||||||
|
QTime timeBegin = QTime::currentTime();
|
||||||
|
qDebug() << QString("[ %1 ] sort started.").arg(name);
|
||||||
|
|
||||||
|
stop = false;
|
||||||
|
data = mergeSortBody(_data);
|
||||||
|
|
||||||
|
emit workerFinished(name, data, timeBegin.msecsTo(QTime::currentTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> QWorker::mergeSortBody(QVector<int> data)
|
||||||
|
{
|
||||||
|
if (data.size() <= 1 || stop)
|
||||||
|
return data;
|
||||||
|
|
||||||
|
QVector<int> left = mergeSortBody(data.mid(0, data.size() / 2));
|
||||||
|
QVector<int> right = mergeSortBody(data.mid(left.size(), data.size() - left.size()));
|
||||||
|
|
||||||
|
return mergeBody(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> QWorker::mergeBody(QVector<int> left, QVector<int> right)
|
||||||
|
{
|
||||||
|
QVector<int> result;
|
||||||
|
result.reserve(left.size() + right.size());
|
||||||
|
|
||||||
|
int leftFirstIndex = 0;
|
||||||
|
int rightFirstIndex = 0;
|
||||||
|
|
||||||
|
while (leftFirstIndex < left.size() && rightFirstIndex < right.size() && !stop)
|
||||||
|
if (left.at(leftFirstIndex) <= right.at(rightFirstIndex))
|
||||||
|
result.append(left.at(leftFirstIndex++));
|
||||||
|
else
|
||||||
|
result.append(right.at(rightFirstIndex++));
|
||||||
|
|
||||||
|
if (left.size() - leftFirstIndex > 0)
|
||||||
|
result.append(left.mid(leftFirstIndex));
|
||||||
|
if (right.size() - rightFirstIndex > 0)
|
||||||
|
result.append(right.mid(rightFirstIndex));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
void QWorker::bubbleSort(QVector<int> _data)
|
||||||
|
{
|
||||||
|
QTime timeBegin = QTime::currentTime();
|
||||||
|
qDebug() << QString("[ %1 ] sort started.").arg(name);
|
||||||
|
|
||||||
|
stop = false;
|
||||||
|
data = _data;
|
||||||
|
|
||||||
|
bool swapped;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
swapped = false;
|
||||||
|
for (int i = 1; i < data.size() && !stop; ++i)
|
||||||
|
if (data.at(i-1) > data.at(i))
|
||||||
|
{
|
||||||
|
int tmp = data.at(i);
|
||||||
|
data[i] = data.at(i-1);
|
||||||
|
data[i-1] = tmp;
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (swapped != false && !stop);
|
||||||
|
|
||||||
|
emit workerFinished(name, data, timeBegin.msecsTo(QTime::currentTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWorker::quickSort(QVector<int> _data)
|
||||||
|
{
|
||||||
|
QTime timeBegin = QTime::currentTime();
|
||||||
|
qDebug() << QString("[ %1 ] sort started.").arg(name);
|
||||||
|
|
||||||
|
stop = false;
|
||||||
|
data = _data;
|
||||||
|
|
||||||
|
quickSortBody(data);
|
||||||
|
|
||||||
|
emit workerFinished(name, data, timeBegin.msecsTo(QTime::currentTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWorker::quickSortBody(QVector<int> &data, int start, int end)
|
||||||
|
{
|
||||||
|
if (end == -1) end = data.size() - 1;
|
||||||
|
|
||||||
|
if (start >= end || stop) return;
|
||||||
|
|
||||||
|
int base = quickSortPart(data, start, end);
|
||||||
|
|
||||||
|
quickSortBody(data, start, base - 1);
|
||||||
|
quickSortBody(data, base + 1, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
int QWorker::quickSortPart(QVector<int> &data, int start, int end)
|
||||||
|
{
|
||||||
|
int temp;
|
||||||
|
int marker = start;
|
||||||
|
|
||||||
|
for (int i = start; i <= end && !stop; ++i)
|
||||||
|
if (data.at(i) < data.at(end))
|
||||||
|
{
|
||||||
|
temp = data.at(marker);
|
||||||
|
data[marker] = data.at(i);
|
||||||
|
data[i] = temp;
|
||||||
|
marker++;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = data.at(marker);
|
||||||
|
data[marker] = data.at(end);
|
||||||
|
data[end] = temp;
|
||||||
|
|
||||||
|
return marker;
|
||||||
|
}
|
39
QWorker.h
Normal file
39
QWorker.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef QWORKER_H
|
||||||
|
#define QWORKER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
class QWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QWorker(QString _name, QObject *parent = nullptr);
|
||||||
|
~QWorker();
|
||||||
|
|
||||||
|
volatile bool stop;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void mergeSort(QVector<int> _data);
|
||||||
|
void bubbleSort(QVector<int> _data);
|
||||||
|
void quickSort(QVector<int> _data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void workerFinished(QString name, QVector<int> data, int msecs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<int> mergeSortBody(QVector<int> data);
|
||||||
|
QVector<int> mergeBody(QVector<int> left, QVector<int> right);
|
||||||
|
|
||||||
|
void quickSortBody(QVector<int> &data, int start = 0, int end = -1);
|
||||||
|
int quickSortPart(QVector<int> &data, int start, int end);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString name;
|
||||||
|
QVector<int> data;
|
||||||
|
|
||||||
|
private: // sort sub
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QWORKER_H
|
15
main.cpp
Normal file
15
main.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "QMain.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication a(argc, argv);
|
||||||
|
QMain shell;
|
||||||
|
|
||||||
|
QObject::connect(&shell, SIGNAL(closeProgram()), &a, SLOT(quit()));
|
||||||
|
QTimer::singleShot(0,&shell,SLOT(beginSort()));
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user