// main.cpp
#include <QtCore/QCoreApplication>
#include "manager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
manager m_manager;
m_manager.start();
return a.exec();
}
// manager.h
#pragma once
#include <QObject>
#include <qmutex.h>
#include <qrandom.h>
#include <qthread.h>
#include <qdebug.h>
#include <qlist.h>
#include <qwaitcondition.h>
#include "Producer.h"
#include "consumer.h"
class manager : public QObject
{
Q_OBJECT
public:
explicit manager(QObject *parent = nullptr);
~manager();
signals:
public slots:
void start();
void ready();
private:
QList<int> data;
QMutex mutex;
QThread producerThread;
QThread consumerThread;
QWaitCondition condition;
Producer producer;
consumer m_consumer;
};
// manager.cpp
#include "manager.h"
manager::manager(QObject *parent)
: QObject(parent)
{
connect(&producerThread, &QThread::started,&producer,&Producer::start,Qt::QueuedConnection);
connect(&producer, &Producer::ready, this, &manager::ready, Qt::QueuedConnection);
connect(&consumerThread, &QThread::started, &m_consumer, &consumer::start, Qt::QueuedConnection);
producerThread.setObjectName("Producer Thread");
consumerThread.setObjectName("consumer Thread");
this->thread()->setObjectName("Main Thread");
producer.moveToThread(&producerThread);
m_consumer.moveToThread(&consumerThread);
}
manager::~manager()
{
}
void manager::start()
{
producer.setMutex(&mutex);
producer.setData(&data);
m_consumer.setMutex(&mutex);
m_consumer.setData(&data);
m_consumer.setCondition(&condition);
producerThread.start();
consumerThread.start();
}
void manager::ready()
{
qInfo() << "Data is ready" << this->thread();
condition.wakeAll();
}
// producer.h
#pragma once
#include <QObject>
#include <qmutex.h>
#include <qrandom.h>
#include <qthread.h>
#include <qdebug.h>
#include <qlist.h>
class Producer : public QObject
{
Q_OBJECT
public:
explicit Producer(QObject *parent = nullptr);
~Producer();
void setData(QList<int>* data);
void setMutex(QMutex* mutex);
signals:
void ready();
public slots:
void start();
private:
QList<int>* data;
QMutex* mutex;
};
// producer.cpp
#include "Producer.h"
Producer::Producer(QObject *parent)
: QObject(parent)
{
}
Producer::~Producer()
{
}
void Producer::setData(QList<int>* data)
{
this->data = data;
}
void Producer::setMutex(QMutex* mutex)
{
this->mutex = mutex;
}
void Producer::start()
{
do {
int value = QRandomGenerator::global()->bounded(1000);
mutex->lock();
data->append(value);
if (data->length() >= 100) emit ready();
mutex->unlock();
} while (true);
}
// consumer.h
#pragma once
#include <QObject>
#include <qmutex.h>
#include <qrandom.h>
#include <qthread.h>
#include <qdebug.h>
#include <qlist.h>
#include <qwaitcondition.h>
class consumer : public QObject
{
Q_OBJECT
public:
explicit consumer(QObject *parent = nullptr);
~consumer();
void setData(QList<int>* data);
void setMutex(QMutex* mutex);
void setCondition(QWaitCondition* condition);
signals:
public slots:
void start();
private:
QList<int>* data;
QMutex* mutex;
QWaitCondition* condition;
};
// consumer.cpp
#include "consumer.h"
consumer::consumer(QObject *parent)
: QObject(parent)
{
}
consumer::~consumer()
{
}
void consumer::setData(QList<int>* data)
{
this->data = data;
}
void consumer::setMutex(QMutex* mutex)
{
this->mutex = mutex;
}
void consumer::setCondition(QWaitCondition* condition)
{
this->condition = condition;
}
void consumer::start()
{
qInfo() << "Staring consumer on: " << this->thread();
do
{
qInfo() << "Consuming on: " << this->thread();
mutex->lock();
data->clear();
// pause
condition->wait(mutex);
mutex->unlock();
} while (true);
}
