This commit is contained in:
GenZmeY 2018-04-13 00:32:28 +03:00 committed by GitHub
parent 0e95f69932
commit 47e3785ef6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 352 additions and 0 deletions

99
QMain.cpp Normal file
View 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
View 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
View 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
View 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
View 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
View 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();
}