[英]How to properly quit Qt application with worker thread?
退出Qt应用程序的最佳做法是什么? 我做这样的事情
int main(int argc, char *argv[])
{
MyApplication app(argc, argv);
return myApp.exec();
}
MyApplication::MyApplication( int& argc, char** argv ) :
QApplication( argc, argv )
{
m_window= new MyWidget();
m_worker= new MyWorker();
m_threadWorker = new QThread;
m_worker->moveToThread(m_threadWorker);
connect(this, SIGNAL(aboutToQuit()),m_worker,SLOT(quit()));
connect(m_worker, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
connect(m_worker, SIGNAL(finished()), m_threadWorker, SLOT(quit()));
connect(m_threadWorker, SIGNAL(finished()), m_threadWorker, SLOT(deleteLater()));
m_threadWorker->start();
m_window->show();
}
MyApplication::~MyApplication()
{
m_window->deleteLater();
qDebug()<<"MyApplication::~MyApplication()";
}
MyWorker::quit()
{
//longer ending operations freeing resources
emit finished();
qDebug() << "MyWorker::quit() emit finished()";
}
MyWorker::~MyWorker()
{
qDebug() << "MyWorker::~MyWorker()";
}
问题在于,Worker析构函数通常不运行。 我担心未正确终止工作进程会不时导致应用程序崩溃。 我在该线程中使用摄像头,因此,如果摄像头循环处于活动状态,则释放会花费更多时间,并且通常不会发出完成对象,因此永远不会调用析构函数。
问题在于aboutToQuit
不等待工作人员完成。 您必须明确地等待它这样做:
connect(this, &MyApplication::aboutToQuit,
this, &MyApplication::stopWorker);
// also, change up your connects a little to make shure everything gets deleted properly
connect(m_worker, &MyWorker::finished,
m_threadWorker, &QThread::quit,
Qt::DirectConnection); //direct connection is needed, because you are blocking the main thread by waiting
connect(m_threadWorker, &QThread::finished,
m_worker, &MyWorker::deleteLater);
MyApplication::stopWorker() {
QMetaObject::invokeMethod(m_worker, "quit");
m_threadWorker->wait();
m_threadWorker->deleteLater();
}
但是,这将在等待工作人员完成时“冻结”您的应用程序。 如果要在等待时保持响应,请改用MyApplication::stopWorker
的本地QEventLoop
并将其用作:
MyApplication::stopWorker() {
QEventLoop stopLoop;
connect(m_threadWorker, &QThread::finished,
&stopLoop, &QEventLoop::quit);
QMetaObject::invokeMethod(m_worker, "quit");
stopLoop.exec();
m_threadWorker->deleteLater();
}
感谢您的评论,此解决方案有效
int main(int argc, char *argv[])
{
MyApplication app(argc, argv);
return myApp.exec();
}
MyApplication::MyApplication( int& argc, char** argv ) :
QApplication( argc, argv )
{
m_window= new MyWidget();
m_worker= new MyWorker();
m_threadWorker = new QThread;
m_worker->moveToThread(m_threadWorker);
connect(this, SIGNAL(aboutToQuit()),m_worker,SLOT(quit()),Qt::QueuedConnection);
connect(m_worker, SIGNAL(finished()), m_threadWorker, SLOT(quit()),Qt::DirectConnection);
connect(m_threadWorker, SIGNAL(finished()), m_worker, SLOT(deleteLater()));
m_threadWorker->start();
m_window->show();
}
MyApplication::~MyApplication()
{
m_threadWorker->wait();
m_threadWorker->deleteLater();
m_window->deleteLater();
qDebug()<<"MyApplication::~MyApplication()";
}
MyWorker::quit()
{
//longer ending operations freeing resources
emit finished();
qDebug() << "MyWorker::quit() emit finished()";
}
MyWorker::~MyWorker()
{
qDebug() << "MyWorker::~MyWorker()";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.