运行 来自qt中另一个线程的qtconcurrent时如何关闭程序
How to close the programme when running a qtconcurrent from another thread in qt
我正在 运行ning 一个具有多线程的程序。该程序首先有一个主线程/UI 线程运行ning。在这个程序中,我有一个工人和处理程序 class.
工作人员class 正在使用模拟函数来简单地生成随机数。模拟函数连续生成数字而不阻塞任何线程,即通过 Qtconcurrent.
从 main/UI 线程我已将此工作人员 class 放入新线程。处理程序 class 在主线程中 运行ning /UI 负责通过信号槽与其他线程中的工作者 class 运行ning 通信。
到目前为止一切正常。
当我尝试通过简单地单击应用程序十字按钮来关闭程序时,问题就出现了。
程序有点挂起它不关闭。但是,当我不将工作人员放在同一主线程的另一个 class 和 运行 工作人员 class 中时,就没有问题,程序以 0.[=16= 退出]
所以我的问题是如何停止 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;
}
worker.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;
}
handler.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
这里可能发生了什么:用于退出 l_newThread
的信号 toStop_Signal
从未被传递,因为当它被发出时,事件循环已经死了。因此,您的程序卡在等待 l_newThread.wait();
.
中的线程
我完全不明白你为什么要启动这个线程,只是为了在之后使用 QtConcurrent::run
并跨越另一个线程 ...
无论如何,一旦您确定您的 worker 已停止(根据您发布的输出,您是),您可以直接在 main
中安全地退出(基本上无用的)线程:
int result = app.exec();
l_newThread.exit(); //just quit it
l_newThread.wait();
return result;
那你就可以去掉这个连接了:
QObject::connect(l_handler,&handler::toStop_Signal,&l_newThread, &QThread::quit);
和(我猜)处理程序完全一样。
我正在 运行ning 一个具有多线程的程序。该程序首先有一个主线程/UI 线程运行ning。在这个程序中,我有一个工人和处理程序 class.
工作人员class 正在使用模拟函数来简单地生成随机数。模拟函数连续生成数字而不阻塞任何线程,即通过 Qtconcurrent.
从 main/UI 线程我已将此工作人员 class 放入新线程。处理程序 class 在主线程中 运行ning /UI 负责通过信号槽与其他线程中的工作者 class 运行ning 通信。
到目前为止一切正常。
当我尝试通过简单地单击应用程序十字按钮来关闭程序时,问题就出现了。 程序有点挂起它不关闭。但是,当我不将工作人员放在同一主线程的另一个 class 和 运行 工作人员 class 中时,就没有问题,程序以 0.[=16= 退出]
所以我的问题是如何停止 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;
}
worker.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;
}
handler.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
这里可能发生了什么:用于退出 l_newThread
的信号 toStop_Signal
从未被传递,因为当它被发出时,事件循环已经死了。因此,您的程序卡在等待 l_newThread.wait();
.
我完全不明白你为什么要启动这个线程,只是为了在之后使用 QtConcurrent::run
并跨越另一个线程 ...
无论如何,一旦您确定您的 worker 已停止(根据您发布的输出,您是),您可以直接在 main
中安全地退出(基本上无用的)线程:
int result = app.exec();
l_newThread.exit(); //just quit it
l_newThread.wait();
return result;
那你就可以去掉这个连接了:
QObject::connect(l_handler,&handler::toStop_Signal,&l_newThread, &QThread::quit);
和(我猜)处理程序完全一样。