gpt4 book ai didi

c++ - 如何在 QT 中停止 qThread

转载 作者:搜寻专家 更新时间:2023-10-30 23:52:58 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Qt, How to pause QThread immediately

(1 个回答)


4年前关闭。




我想知道如何正确停止 QThread。我在一个线程中有一个无限循环,我想在执行特定操作时停止它:

我试过了 :

if (thread->isRunning()){
worker->stop();
thread->terminate();
}

stop() 方法将一个值设置为 false 以退出我的无限循环。

此外,我真的不明白quit()、terminate() 或wait() 之间的区别。有人可以解释我吗?

谢谢。

最佳答案

正确的答案取决于您实际使用的方式 QThread以及您如何实现 stop() .

Qt 中的预期用例假定以下模型:

  • 您创建了一个对象,该对象将做一些有用的工作来响应信号
  • 你创建了一个 `QThread` 并将你的对象移动到这个线程
  • 当您向对象发送信号时,它会在您创建的 `QThread` 中处理

  • 现在,您需要了解实际实现方式的一些内部原理。 Qt 中有多种信号“模型”,在某些情况下,当您“发送信号”时,您实际上只需调用“槽”函数即可。这是一个“直接”插槽连接,在这种情况下 slot()将在调用者线程中执行,一个引发信号的线程。所以为了与另一个线程通信,Qt 允许另一种信号, 排队连接 .而不是调用 slot() , 调用者给拥有这个槽的对象留下一条消息。与此对象关联的线程将读取此消息(稍后)并执行 slot()本身。

    现在您可以了解在创建和执行 QThread 时发生了什么。 .新创建的线程将执行 QThread::run()默认情况下,将执行 QThread::exec()这只不过是一个无限循环,它为与线程关联的对象查找消息并将它们传输到这些对象的插槽中。调用 QThread::quit()向此队列发布终止消息。当 QThread::exec()将读取它,它将停止进一步处理事件,退出无限循环并轻轻终止线程。

    现在,正如您可能猜到的,为了接收终止消息,必须满足两个条件:
  • 你应该运行 `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/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com