QThread :: quit()是立即结束线程还是等待直到返回事件循环?
有很多Qt多线程教程,其中指出可以使用以下两行安全地停止QThread
.
There are a lot of Qt multi-threading tutorials out there that state that a QThread
can be stopped safely using the following two lines.
qthread.quit(); // Cause the thread to cease.
qthread.wait(); // Wait until the thread actually stops to synchronize.
我有很多代码这样做,在大多数情况下,在停止线程的情况下,我将始终设置自己的cancel标志并在执行过程中经常检查它(这是正常的做法).直到现在,我还以为调用quit可能会使线程不再执行任何等待信号(例如,排队的信号将不再调用其插槽),而是仍然等待当前正在执行的插槽结束.
I have a lot of code doing this, and in most cases of stopping thread, I'll always set my own cancel flag and check it often during execution (as is the norm). Until now, I was thinking that calling quit would perhaps cause the thread to simply no longer execute any waiting signals (e.g. signals that are queued will no longer have their slots called) but still wait on the currently executing slot to finish.
但是我想知道我是否正确,或者quit()
是否实际上停止了执行该线程的线程,例如,如果未完成的事情(例如文件描述符尚未关闭)肯定应该是,即使在大多数情况下,我的工作对象将清理这些资源,但如果我确切地知道戒烟的工作原理,我会感觉更好.
But I'm wondering if I was right or if quit()
actually stops the execution of the thread where it's at, for instance if something is unfinished, like a file descriptor hasn't been closed, it definitely should be, even though in most cases my worker objects will clean up those resources, I'd feel better if I knew exactly how quit works.
我之所以这样问,是因为QThread::quit()
文档说它等同于调用QThread :: exit(0)".我相信这意味着线程将立即停止在其所在的位置.但是调用退出的堆栈帧会发生什么?
I'm asking this because QThread::quit()
documentation says that it's "equivalent to calling QThread::exit(0)". I believe this means that the thread would immediately stop where it's at. But what would happen to the stackframe that quit was called in?
QThread::quit
不执行任何操作.因此,它不一定会停止线程.
QThread::quit
does nothing if the thread does not have an event loop or some code in the thread is blocking the event loop. So it will not necessarily stop the thread.
所以QThread::quit
告诉线程的事件循环退出.调用它后,线程将在控件返回到线程的事件循环后立即完成.
So QThread::quit
tells the thread's event loop to exit. After calling it the thread will get finished as soon as the control returns to the event loop of the thread.
如果要阻止事件循环(例如通过循环工作),则必须添加某种中止标志.这可以通过一个布尔型的成员变量来实现,该成员变量是public或至少具有public setter方法.然后,您可以通过设置中止标志来告诉线程从外部(例如从您的主线程)尽快退出.当然,这需要您的线程代码定期检查中止标志.
You will have to add some kind of abort flag if you are blocking event loop for example by working in a loop. This can be done by a boolean member variable that is public or at least has a public setter method. Then you can tell the thread to exit ASAP from outside (e.g. from your main thread) by setting the abort flag. Of course this will require your thread code to check the abort flag at regular intervals.
您还可以通过 QThread::terminate()
,但这是一个非常糟糕的做法,因为它可能会在代码中未定义的位置终止线程,这意味着您可能最终会遇到资源永远无法释放的情况和其他令人讨厌的东西.因此,仅当您确实无法解决此问题时才使用它.从其文档中:
You may also force a thread to terminate right now via QThread::terminate()
, but this is a very bad practice, because it may terminate the thread at an undefined position in its code, which means you may end up with resources never getting freed up and other nasty stuff. So use this only if you really can't get around it. From its documentation:
警告:此功能很危险,不建议使用.线程可以在其代码路径中的任何位置终止.修改数据时可以终止线程.线程没有机会自行清理,解锁任何持有的互斥对象等.总之,仅在绝对必要时使用此功能.
Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
当您在线程中使用循环时,我认为这是完成线程的好方法:
I think this is a good way to finish a thread when you are using loops in a thread:
myThread->m_abort = true; //Tell the thread to abort
if(!myThread->wait(5000)) //Wait until it actually has terminated (max. 5 sec)
{
myThread->terminate(); //Thread didn't exit in time, probably deadlocked, terminate it!
myThread->wait(); //We have to wait again here!
}