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