Я запускаю программу с многопоточностью. Сначала в программе работает основной поток/поток пользовательского интерфейса. В этой программе у меня есть рабочий класс и класс обработчика.
Рабочий класс имеет функцию имитации, которая просто генерирует случайное число. Функция имитации непрерывно генерирует число без блокировки какого-либо потока, т. е. через Qtconcurrent.
Из основного потока/потока пользовательского интерфейса я поместил этот рабочий класс в новый поток. Класс обработчика работает в основном потоке /UI и отвечает за связь с рабочим классом, работающим в другом потоке, через сигнальный слот.
Пока все в порядке.
Проблема начинается, когда я пытаюсь закрыть программу, просто нажав на крестик приложения. Программа как бы зависает, не закрывается. Однако, когда я не помещаю рабочего в другой класс и запускаю рабочий класс из того же основного потока/потока пользовательского интерфейса, тогда проблем нет, и программа завершается с 0.
Итак, мой вопрос заключается в том, как остановить Qtconcurrent и, наконец, закрыть другой поток.
Спасибо.
main.cpp
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QThread l_newThread;
Worker* l_worker = new Worker();
handler * l_handler = new handler();
l_worker->moveToThread(&l_newThread);
QObject::connect(&l_newThread, &QThread::started, l_worker, &Worker::Init);
QObject::connect(l_handler,&handler::toStop_Signal,&l_newThread, &QThread::quit);
QObject::connect(l_worker, &Worker::toStop_Signal_Worker, l_handler,&handler::toStop_Slot);
QObject::connect(&app,&QCoreApplication::aboutToQuit, l_worker, &Worker::stop);
// QObject::connect(&app,&QCoreApplication::aboutToQuit, &l_newThread, &QThread::quit);
l_newThread.start();
// l_worker->Init();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
int result = app.exec();
l_newThread.wait();
return result;
}
рабочий.cpp
#include "worker.h"
Worker::Worker(QObject *parent) : QObject(parent)
{
}
void Worker:: Init()
{
m_simulation = true;
simulate();
}
void Worker::simulate()
{
QtConcurrent::run([this]{
QRandomGenerator generator;
while (m_simulation) {
qint32 t = generator.bounded(0,100);
qDebug() << t;
qDebug() << "sleeping for 1 second";
QThread::sleep(1);
}
if (!m_simulation) {
qDebug() << "Killing the concurrent thread";
// QThread::currentThread()->exit();
emit toStop_Signal_Worker();
}
});
}
void Worker::stop()
{
m_simulation = false;
}
обработчик.cpp
#include "handler.h"
handler::handler(QObject *parent) : QObject(parent)
{
}
void handler::toStop_Slot()
{
emit toStop_Signal();
}
Результаты
QML debugging is enabled. Only use this in a safe environment. 19 sleeping for 1 second 55 sleeping for 1 second 70 sleeping for 1 second 69 sleeping for 1 second Killing the concurrent thread