作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这个问题在这里已经有了答案:
Qt, How to pause QThread immediately
(1 个回答)
4年前关闭。
我想知道如何正确停止 QThread。我在一个线程中有一个无限循环,我想在执行特定操作时停止它:
我试过了 :
if (thread->isRunning()){
worker->stop();
thread->terminate();
}
最佳答案
正确的答案取决于您实际使用的方式 QThread
以及您如何实现 stop()
.
Qt 中的预期用例假定以下模型:
slot()
将在调用者线程中执行,一个引发信号的线程。所以为了与另一个线程通信,Qt 允许另一种信号,
排队连接 .而不是调用
slot()
, 调用者给拥有这个槽的对象留下一条消息。与此对象关联的线程将读取此消息(稍后)并执行
slot()
本身。
QThread
时发生了什么。 .新创建的线程将执行
QThread::run()
默认情况下,将执行
QThread::exec()
这只不过是一个无限循环,它为与线程关联的对象查找消息并将它们传输到这些对象的插槽中。调用
QThread::quit()
向此队列发布终止消息。当
QThread::exec()
将读取它,它将停止进一步处理事件,退出无限循环并轻轻终止线程。
QThread
子类化时,通常会违反第一个并覆盖
QThread::run
用他们自己的代码。在大多数情况下,这是一个错误的用法,但它仍然被广泛教授和使用。在您的情况下,您似乎违反了第二个要求:您的代码运行无限循环,因此
QThread::exec()
根本没有得到控制,也没有机会检查它是否需要退出。将您的无限循环丢弃到回收站,
QThread::exec()
已经在为你运行这样的循环。想想如何重写你的代码,让它不运行无限循环,这总是可能的。从“消息到线程”概念的角度考虑您的程序。如果您定期检查某些内容,请创建
QTimer
这将向您的对象发送消息并在您的插槽中执行检查。如果您处理大量数据,请将这些数据拆分为较小的块并写入您的对象,以便它一次处理一个块以响应某些消息。例如。如果您正在逐行处理图像,请创建一个插槽
processLine(int line)
并将信号序列“0,1,2...height-1”发送到该插槽。请注意,您还必须明确调用
QThread::quit()
一旦完成处理,因为事件循环是无限的,当您处理图像的所有行时,它不会“知道”。还可以考虑使用
QtConcurrent
用于计算密集型任务而不是
QThread
.
QThread::terminate()
确实以非常不同的方式停止线程。它只是要求操作系统终止您的线程。操作系统只会在代码中的任意位置突然停止您的线程。线程堆栈内存将被释放,但该堆栈指向的任何内存都不会。如果线程拥有某些资源(例如文件或互斥锁),它将永远不会释放它。涉及将数据写入内存的操作可以在中间停止,并使内存块(例如对象)未完全填充并处于无效状态。正如您可能从这段描述中猜到的那样,您永远不应该拨打
::terminate()
除了在极少数情况下保持线程运行比获取内存和资源泄漏更糟糕的情况。
QThread::wait()
只是一个方便的函数,等到
QThread
停止执行。它适用于
exit()
和
terminate()
.
QThread
继承的子类。并实现您自己的线程终止程序。从本质上讲,退出线程所需的一切只是从
QThread::run()
返回。当有必要并且您不能同时使用时
exit()
也不是
terminate()
为了这个目的。创建您自己的同步原语并使用它来通知您的代码返回。但在大多数情况下,这不是一个好主意,请记住(除非您自己使用
QEventLoop
),在这种情况下,Qt 信号和插槽将无法正常工作。
关于c++ - 如何在 QT 中停止 qThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42679791/
我是一名优秀的程序员,十分优秀!