QThread -使用slot quit()退出线程
QThread - Using a slot quit() to exit the thread
我想在线程完成运行时通知对象。但是,我无法使线程正确退出。我有以下代码:
Processor.cpp
thread = new QThread;
tw = new ThreadWorker;
connect(tw, SIGNAL(updateStatus(QString)), this, SLOT(statusUpdate(QString)));
tw->doSetup(thread, strDic);
tw->moveToThread(thread);
thread->start();
while(thread->isRunning())
{
}
qDebug() << "Thread Finished";
ThreadWorker.cpp
void ThreadWorker::doSetup(QThread *thread, const string &path)
{
_strPath = path;
connect(thread, SIGNAL(started()), this, SLOT(run()));
connect(this, SIGNAL(finished()), thread, SLOT(quit())); //tried terminate() also
}
void ThreadWorker::run()
{
DirectorySearch dicSearch;
vector<string> vecFileList = dicSearch.getFileList(_strPath);
emit updateStatus("Directory Fetched");
emit finished();
}
quit()插槽似乎没有停止线程(QThread::isFinished从不返回true)。有人能给我指路吗?
(注意:ThreadWorker不继承QThread)
假设Processor.cpp
在主线程中运行,则while(thread->isRunning())
循环完全占用了主线程。这意味着你的应用程序的事件循环不能做任何处理,所以信号updateStatus()
,例如,将永远不会被处理。正如评论中提到的,由于QThread
对象是由主线程创建的,因此它的信号也不能工作,因为它们也需要主事件循环来完成它的工作。此外,如果你在主线程中等待你的工作线程做一些事情,为什么要使用工作线程呢?:)
尝试删除while循环,添加一个插槽workDone()
(或任何你想叫它)到Processor.cpp
,并连接到你的Threadworker
的finished()
信号。
我有同样的问题,并找到了答案。我的问题是:QThread.wait()函数的用途是什么?
为了解决你的问题,你不需要在你的while循环中运行QCoreApplication::instance()->processEvents(),你需要做的是,而不是调用quit(),它试图发送一个信号到你的创建线程的事件循环(现在被while循环阻塞),你必须直接调用它。
所以在你的代码中,删除这行:
connect(this, SIGNAL(finished()), thread, SLOT(quit())); //tried terminate() also
而不是:
emit finished();
使用:
this->thread()->quit();
漏掉什么问题解决了。经验教训:不要试图通过qt信号槽机制从工作线程中退出,因为你的信号不会在它们应该在的地方结束(你的工作线程的事件循环),而是在创建线程中结束。你永远不知道那个线程在做什么,也不知道它的事件循环是否正在运行,这对你的工作线程来说应该无关紧要……请直接调用quit。
您可以使用Qt::DirectConnection:
connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
而不是做你的'doSetup'函数…在moveToThread之前,在tw的父节点上的SINGALS和tw中的SLOTS之间建立连接。
我将做4个连接。首先是ThreadWorker中的run方法。这很简单,不言自明。
第二个是从您完成的信号到下面的第三个信号连接。退出线程的信号
第三个应该调用线程的terminate()槽的SIGNAL。这将在连接到run方法时有效地关闭事件循环设置(执行start()时会自动调用exec),并且由于您的run方法不是某种类型的循环,因此将毫无问题地关闭线程。
Forth是从线程终止的()SIGNAL到父线程的SLOT。如果你想在线程死亡的时候做点什么,这将告诉你。
你做上面的连接(如果你需要传递字符串,添加一个变量到run方法和相应的SIGNAL连接,你就会有数据),移动到线程,线程启动,然后做附加到run方法的SIGNAL。随它去吧。当它完成时,它将执行一个已完成的信号,该信号绑定到另一个绑定到线程终止槽的信号。这将终止事件循环并退出线程,将终止的信号推出,以便您可以执行操作。
- std::async 如果线程是从 DLL 创建的,则会阻止进程退出?
- 在线程退出之前,线程分配的内存块是否与线程本身具有相同的相关性?
- STD ::线程不会退出
- C++线程退出循环条件
- gdb 中的线程 0x7fffc57fa700 (LWP 31671) 退出] 是什么意思?
- 如何使用工作线程正确退出Qt应用程序
- Boost.Asio:由于线程退出或应用程序请求,I/O 操作已中止
- 当子线程退出时,如何通知父线程
- 线程已退出,代码为 1:Join() 和 Detach()
- 安全地退出程序 Win32 C++从分离的 std::线程
- 在另一个线程正在运行的情况下退出应用程序时出错
- C++提升线程组.interrupt_all()导致主线程也退出
- 确定线程是否已退出
- 在退出应用程序时安全退出Qt线程
- c++允许后台线程在退出应用程序之前完成
- 如果线程在调用pthread_join之前退出,该怎么办
- JNI - Java 在本机线程完成执行之前退出
- 线程退出时通知Waiters
- 多线程Qt应用程序在退出时不会停止
- 如何以线程安全的方式退出 C++03 中的程序