Qt_IM_56 - 8BitsCoding/RobotMentor GitHub Wiki
pool을 통해서 worker를 관리한다.
// main.cpp
#include <QtCore/QCoreApplication>
#include <qdebug.h>
#include "pool.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
pool p;
for (int i = 0; i < 100; i++) {
p.work(i);
}
return a.exec();
}
#pragma once
#include <QObject>
#include <qtimer.h>
#include <qrandom.h>
#include <qdebug.h>
class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = nullptr);
~worker();
bool isBusy();
signals:
void started();
void finished();
public slots:
void timeout();
void work(int value);
private:
QTimer m_timer;
bool m_busy = false;
};
#include "worker.h"
worker::worker(QObject *parent)
: QObject(parent)
{
}
worker::~worker()
{
}
void worker::timeout()
{
m_busy = false;
emit finished();
}
void worker::work(int value)
{
m_busy = true;
qInfo() << "Starting work: " << QString::number(value);
int num = QRandomGenerator::global()->bounded(1000, 5000);
m_timer.singleShot(num, this, &worker::timeout);
emit started();
}
bool worker::isBusy()
{
return m_busy;
}
#pragma once
#include <QObject>
#include <Qdebug.h>
#include <qvector.h>
#include <qtimer.h>
#include "worker.h"
class pool : public QObject
{
Q_OBJECT
public:
explicit pool(QObject *parent = nullptr);
~pool();
signals:
public slots:
void work(int value);
void started();
void finished();
void checkwork();
private:
QVector<worker*> m_workers;
QVector<int> m_work;
QTimer m_timer;
};
#include "pool.h"
pool::pool(QObject *parent)
: QObject(parent)
{
for (int i = 0; i < 5; i++) {
worker* w = new worker(this);
w->setObjectName("Worker: " + QString::number(i));
connect(w, &worker::started, this, &pool::started);
connect(w, &worker::finished, this, &pool::finished);
m_workers.append(w);
qInfo() << "Worker ready: " << w->objectName();
}
connect(&m_timer, &QTimer::timeout, this, &pool::checkwork);
m_timer.setInterval(200);
m_timer.start();
}
pool::~pool()
{
m_timer.stop();
qDeleteAll(m_workers);
m_workers.clear();
}
void pool::work(int value)
{
m_work.append(value);
checkwork();
}
void pool::started()
{
worker* w = qobject_cast<worker*>(sender());
qInfo() << "Started: " << w->objectName();
}
void pool::finished()
{
worker* w = qobject_cast<worker*>(sender());
qInfo() << "Finished: " << w->objectName();
}
void pool::checkwork()
{
if (m_work.isEmpty()) return;
foreach(worker * w, m_workers)
{
if (!w->isBusy()) {
w->work(m_work.takeFirst());
if (m_work.isEmpty()) return;
}
}
}