简体   繁体   English

QThread-使用插槽quit()退出线程

[英]QThread - Using a slot quit() to exit the thread

I want to inform an object when a thread has finished running. 我想在线程完成运行时通知对象。 However, I cannot get the thread to exit properly. 但是,我无法使线程正常退出。 I have the following code: 我有以下代码:

Processor.cpp 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 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();
}

The quit() slot does not seem to stop the thread (QThread::isFinished never returns true). quit()插槽似乎并未停止线程(QThread :: isFinished从不返回true)。 Can someone guide me in the right direction? 有人能引导我朝正确的方向发展吗?

(Note: ThreadWorker does not inherit from QThread) (注意:ThreadWorker不继承自QThread)

Assuming that Processor.cpp is running in your main thread, the while(thread->isRunning()) loop has your main thread completely tied up. 假设Processor.cpp在您的主线程中运行, while(thread->isRunning())循环while(thread->isRunning())您的主线程完全捆绑在一起。 This means that your application's event loop cannot do any processing so the signal updateStatus() for example, will never get processed. 这意味着您的应用程序的事件循环无法执行任何处理,因此,例如信号updateStatus()将永远不会得到处理。 As mentioned in the comments, since the QThread object is created by the main thread, its signals won't work either since they will also require the main event loop to be doing its thing. 正如评论中提到的那样,由于QThread对象是由主线程创建的,因此它的信号也不起作用,因为它们还需要主事件循环来完成其工作。 Besides, if you are waiting in your main thread for your worker thread to do something, why use a worker thread at all? 此外,如果您在主线程中等待工作线程执行某项操作,为什么还要使用工作线程呢? :) :)

Try removing the while loop, add a slot workDone() (or whatever you want to call it) to Processor.cpp and connect that to your Threadworker 's finished() signal. 尝试删除while循环,增加槽workDone()或任何你想将它命名),以Processor.cpp和连接到您的Threadworkerfinished()信号。

I had the same problem and found the answer. 我有同样的问题,找到了答案。 Here is my question: What is the use of QThread.wait() function? 这是我的问题: QThread.wait()函数的用途是什么?

To solve your problem, you don't need to run the QCoreApplication::instance()->processEvents() in your while loop, what you need to do is, instead of invoking the quit() which tries to send a signal to your creating thread's event loop (which is now blocked by the while loop), you have to call it directly. 要解决您的问题,您不需要在while循环中运行QCoreApplication :: instance()-> processEvents(),您需要做的是,而不是调用尝试向其发送信号的quit()。创建线程的事件循环(现在被while循环阻止),您必须直接调用它。

So for your code, drop the line: 因此,对于您的代码,删除以下行:

connect(this, SIGNAL(finished()), thread, SLOT(quit())); //tried terminate() also

And instead of: 而不是:

emit finished();

Use: 采用:

this->thread()->quit();

Tada... problem solved. 多田...问题解决了。 Lesson learned: don't try to exit a worker thread by the qt signal-slot mechanism from within it, because your signals do not end up where they are supposed to (your worker thread's event loop), but they end up in the creating thread instead. 经验教训:不要尝试通过qt signal-slot机制从工作线程中退出工作线程,因为您的信号不会最终到达预期的位置(您的工作线程的事件循环),但最终会导致创建线程代替。 You never know what that thread is doing, and if its event loop is running or not, and this shouldn't be of business to your worker thread anyways... Instead, call the quit directly. 您永远不会知道该线程在做什么,以及它的事件循环是否正在运行,无论如何这都不应该与您的工作线程有关……而是直接调用quit。

You can use Qt::DirectConnection: 您可以使用Qt :: DirectConnection:

connect(this, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection); 

This stops the thread. 这将停止线程。

Instead of doing your 'doSetup' function... before you moveToThread, setup connections between SINGALS on tw's parent and SLOTS in tw. 在moveToThread之前,无需执行“ doSetup”功能...,而是在tw的父代上的SINGALS与tw的SLOTS之间设置连接。

I would do 4 connections. 我会做4个连接。 First is to the run method in ThreadWorker. 首先是ThreadWorker中的run方法。 Thats simple and self explainatory enough. 多数民众赞成在简单和自我解释。

Second is from your finished signal to the third SIGNAL connection below. 第二个是从完成的信号到下面的第三个SIGNAL连接。 A SIGNAL that quits the thread 退出线程的信号

Third to a SIGNAL that should call the terminate() slot of the thread. 第三个信号应该调用线程的terminate()插槽。 This will effectively close the event loop setup when you connect to the run method (exec is auto called when you do a start()) and since your run method isn't a loop of some sort, will close the thread without issue. 当您连接到run方法时,这将有效地关闭事件循环设置(执行start()时会自动调用exec),并且由于run方法不是某种形式的循环,因此将关闭线程而不会出现问题。

Forth is from the thread's terminated() SIGNAL to a SLOT in tw's parent. 第四个是从线程的Terminate()SIGNAL到tw的父代中的SLOT。 This will show you when the thread is dead if you want to do something at that point. 如果您想在那时执行某操作,它将在线程死时向您显示。

You do the above connections (if you need to pass in the string, add a variable to the run method and corresponding SIGNAL connection and you'll have the data), move to thread, thread start, then do the SIGNAL attached to the run method. 您完成了上述连接(如果需要传递字符串,将变量添加到run方法和相应的SIGNAL连接中,您将获得数据),移至线程,启动线程,然后将SIGNAL附加到运行中方法。 Let it do its thing. 让它做自己的事。 When its finished, it will do a finished signal that gets tied to another signal that gets tied to the threads terminated slot. 完成后,它将执行一个完成信号,该信号与另一个与线程终止插槽的信号相关的信号。 This will kill the event loop and exit the thread, pushing a terminated signal out so you can then do something. 这将杀死事件循环并退出线程,将终止的信号推出,以便您可以执行某些操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 QThread: slot quit() 永远不会被调用,因此线程 wait() 是永远的 - QThread: slot quit() is never invoked and hence the thread wait() is forever QThread::exit 或 QThread::quit 不会终止由 derived class 创建的线程 - QThread::exit or QThread::quit won't terminate the thread created by derived class QThread :: quit是否可以从正在运行的线程中使用 - Is QThread::quit usabled from within the running thread QThread 线程间通信:连接到 &amp;QThread::quit 与连接到 lambda [&amp;thread] { thread-&gt;quit();} 的奇怪行为 - QThread interthread communication: strange behavior connecting to &QThread::quit vs connecting to a lambda [&thread] { thread->quit();} QObject:没有这样的插槽QThread :: readyRead() - QObject: no such slot QThread::readyRead() Qt QThread使用信号/插槽从工人到GUI的麻烦 - Qt QThread trouble using signal/slot going from worker to gui 停止Qt线程:调用exit()或quit()不会停止线程执行 - Stop Qt Thread : calling exit() or quit() does not stop the thread execution 使用 Qthread-Qt5 创建新线程 - creating new thread using Qthread-Qt5 QThread :: quit()会立即结束线程还是等到返回事件循环? - Does QThread::quit() immediately end the thread or does it wait until returning to the event loop? 在Qt中,当事件循环的线程拥有的QObject上的一个槽正在执行时,QThread的事件循环是否阻塞? - In Qt, does a QThread's event loop block while a slot on a QObject owned by the event loop's thread is executing?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM