QT(11)- QThread

1 简介

QThread:具有可选事件循环的低级 API
QThread是 Qt 中所有线程控制的基础。每个QThread实例表示并控制一个线程。

QThread可以直接实例化,也可以子类化。实例化QThread提供了一个并行事件循环,允许在辅助线程中调用QObject插槽。对 QThread进行子类化允许应用程序在启动其事件循环之前初始化新线程,或者在没有事件循环的情况下运行并行代码。

QThread 会在线程运行时通过信号通知你started() 和finished(), 或者你可以使用isFinished() 和isRunning() 来查询线程的状态。

您可以通过调用停止线程exit() 或者quit(). 在极端情况下,您可能想要强行terminate() 一个正在执行的线程。然而,这样做是危险的。

使用wait() 阻塞调用线程,直到另一个线程完成执行(或直到指定的时间过去)。

QThread 还提供静态的、平台独立的休眠函数:sleep(),msleep(), 和usleep() 分别允许完整的秒、毫秒和微秒分辨率。

2 枚举

在这里插入图片描述

3 函数

3.1 eventDispatch

QAbstractEventDispatcher *QThread::eventDispatcher() const
它返回线程内部的事件分发器。
事件分发器是Qt内部使用的对象,用于分发事件到与线程关联的对象。它是Qt事件系统的一部分,在应用程序的主线程中,事件分发器会在事件循环中不断地分发事件。在其他线程中,事件分发器用于处理线程相关的事件,例如,线程完成信号或其他自定义事件。

通过使用这个函数,可以访问该线程内部的事件分发器,并对其进行配置或访问。但是,一般情况下,不需要直接访问事件分发器。

void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
setEventDispatcher 是QThread类中的一个成员函数,用于在线程中设置一个事件分发器。

这个函数接受一个QAbstractEventDispatcher指针作为参数,并将其设置为线程的事件分发器。事件分发器是Qt内部使用的对象,用于处理线程内部的事件。通过使用这个函数,可以为线程定制事件分发器,以满足特定需求。

一般情况下,不需要使用这个函数,因为Qt会自动为每个线程分配一个适当的事件分发器。但是,如果需要定制线程内部的事件处理,则可以使用这个函数。

3.2 exit

void QThread::exit(int returnCode = 0)
exit 函数告诉线程的事件循环(不是线程)退出,并以一个返回码作为结果。

调用此函数后,该线程离开事件循环并从调用 QEventLoop::exec() 的地方返回。 QEventLoop::exec() 函数的返回值为 returnCode。

按照惯例,returnCode 为0表示成功,任何非零值表示错误。

请注意,与同名的C库函数不同,该函数确实返回给调用者,因为是事件处理停止了。

在此线程中,不会再启动任何QEventLoop,直到再次调用 QThread::exec()。如果 QThread::exec() 中的事件循环没有运行,则下一次调用 QThread::exec() 也将立即返回。

使用该函数的常见场景是在线程中执行任务完成后终止线程的执行,以避免在没有任务的情况下继续执行无用代码。

3.3 isfinished

bool QThread::isFinished() const
该函数用于检查线程是否已经结束。如果线程已结束,则返回 true,否则返回 false。

线程的结束是指该线程的 run() 函数已经返回。因此,在线程结束后,如果再次调用该函数,它将返回 true。

3.4 requestInterruption

bool isInterruptionRequested() const
如果应该停止在此线程上运行的任务,则返回 true。可以通过以下方式请求中断requestInterruption().

此功能可用于使长时间运行的任务完全可中断。永远不要检查或操作此函数返回的值是安全的,但建议在长时间运行的函数中定期这样做。注意不要过于频繁地调用它,以保持较低的开销。

该函数返回一个布尔值,表示线程是否被请求中断。

应用场景:当我们需要在线程运行时随时取消它,可以使用该函数来实现。

方法:

首先需要在线程的实现中,定期调用该函数,如果函数返回 true,表示线程被请求中断。
然后退出线程的循环,让线程终止。

void MyThread::run()
{
   while (!isInterruptionRequested())
   {
      //do some work
      //check periodically if the thread needs to be stopped
   }
}

QThread *thread = new QThread;
thread->start();
//Later, in another thread
thread->requestInterruption();

void requestInterruption()
请求中断线程。该请求是建议性的,由线程上运行的代码决定是否以及如何响应此类请求。此函数不会停止线程上运行的任何事件循环,也不会以任何方式终止它。

3.5 isRunning

bool QThread::isRunning() const
true如果线程正在运行则返回;否则返回false。

3.4 loopLevel

int QThread::loopLevel() const
QThread::loopLevel() 函数是 Qt 库中的成员函数,用于返回当前线程的事件循环深度。事件循环深度指的是在当前线程中有多少个事件循环正在执行。

例如,如果当前线程中有一个事件循环正在执行,那么 QThread::loopLevel() 函数将返回 1;如果当前线程中有两个事件循环正在执行,那么函数将返回 2,以此类推。

可以通过这个函数来判断线程中是否存在事件循环,从而决定是否执行一些特定的操作。

3.5 priority

QThread::Priority QThread::priority() const
返回正在运行的线程的优先级。如果线程未运行,则此函数返回InheritPriority

void setPriority(QThread::Priority priority)
这个函数用于设置正在运行的线程的优先级。如果线程没有运行,则此函数什么也不做,并立即返回。要以特定优先级启动线程,请使用start()。

priority参数可以是QThread :: Priority枚举中的任何值,除了InheritPriority。

优先级参数的效果取决于操作系统的调度策略。特别是,在不支持线程优先级的系统上(例如Linux)

3.6 StackSize 堆栈大小

void QThread::setStackSize(uint stackSize)
这个函数用于设置线程的堆栈大小。如果线程正在运行,则此函数不会有任何效果,并立即返回。如果要以特定的堆栈大小启动线程,请使用start()。

stackSize参数是堆栈大小,以字节为单位。默认堆栈大小取决于操作系统,通常为2 MB。

注意:在某些操作系统上,设置堆栈大小不受支持,在这些系统上,该函数可能不起作用,因此需要检查该函数的返回值。

uint QThread::stackSize() const
返回线程的最大堆栈大小(如果设置为setStackSize()); 否则返回零。

3.7 wait

bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
这个函数会等待线程结束,直到 deadline 到期。
bool wait(unsigned long time)
这个函数会等待线程结束,最多等待 time 毫秒。

如果在等待期间线程已经结束,那么两个函数都会立即返回 true。否则,如果等待超时或者等待被其他线程中断,那么它们将返回 false。

如果等待的时间到了,但是线程还没有结束,那么 wait() 函数将返回 false。这表示在等待的过程中,线程没有终止,因此不需要等待

4 虚函数

virtual bool event(QEvent *event) override

event() 是 QObject 类中的虚拟函数,在继承类中被重写可以自定义处理事件。QThread 继承自 QObject,所以也可以重写 event() 函数。

event() 函数通过接收到的 QEvent 对象参数来处理不同类型的事件。这样,你可以定制线程的行为,比如,当线程接收到一个特定的事件时,它可以做出特定的反应。

在 event() 函数中,你可以对事件进行判断,根据事件类型执行不同的操作。如果 event() 函数返回 true,那么这个事件就被认为已经处理过;否则,事件会继续传递到父对象。

注意:QThread 不是一个 GUI 线程,所以不能在它的 event() 函数中调用 GUI 函数(例如:QMessageBox)。如果需要在线程中调用 GUI 函数,请使用 signals 和 slots。

5 Public Slots

5.1 quit

void quit()
告诉线程的事件循环以返回码 0(成功)退出。相当于调用QThread::exit(0).
如果线程没有事件循环,则此函数不执行任何操作。

5.2 start

void start(QThread::Priority priority = InheritPriority)
通过调用开始执行线程run(). 操作系统会根据priority范围。如果线程已经在运行,则此函数不执行任何操作。
的影响priority参数取决于操作系统的调度策略。特别是,priority在不支持线程优先级的系统上将被忽略(例如在 Linux 上)

因为优先级需要在线程运行的时候设置,所以如果需要设置优先级,可以在使用start时就直接设置。

5.3 terminate

void terminate()
这个函数是用来终止线程的执行的。根据操作系统的调度策略,线程可能立刻终止,也可能不会。在使用terminate()函数后,使用QThread::wait()来确保线程已经终止。

当线程终止时,所有等待该线程结束的线程将被唤醒。

注意,使用 “terminate()” 终止线程是不推荐的,因为它可能导致线程执行未完成的任务,导致程序状态不一致。正确的做法是在线程执行代码中设置标志,让线程自行退出

6 信号

void finished()
finished() 是 QThread 类的信号,在线程结束后发出。这个信号通常用来在线程结束后释放相关资源,或执行清理操作。

换句话说,它是一个通知,告诉线程的使用者,线程已经结束了。

这个信号可以连接到QObject::deleteLater(), 以释放该线程中的对象。

注意:如果关联的线程被终止使用terminate(), 未定义从哪个线程发出该信号。

注意:这是一个私人信号。它可用于信号连接,但不能由用户发射。

void started()
当相关线程开始执行时,在调用run()函数之前,该信号从线程发出。

注意:这是一个私有信号。它可用于信号连接,但不能由用户发出。

7 静态公有函数

7.1 create

QThread * create(Function &&f, Args &&... args)
c++17标准适用

template <typename Function> QThread *QThread::create(Function &&f)
创建一个新的QThread对象,它将执行函数f。

新线程没有启动——它必须通过显式调用start()来启动。这允许您连接到它的信号,将QObjects移动到线程,选择新线程的优先级等等。函数f将在新线程中被调用。

返回新创建的QThread实例。

注意:调用者获得返回的QThread实例的所有权。

警告:不要在返回的QThread实例上调用start()超过一次;这样做将导致未定义的行为。

7.2 currentThread

QThread * currentThread()
返回一个指向QThread的指针,该QThread管理当前执行的线程

7.3 currentThreadId

Qt::HANDLE currentThreadId()
返回当前执行线程的线程句柄。

警告:此函数返回的句柄用于内部目的,不应在任何应用程序代码中使用。

注意:在Windows上,这个函数返回由Win32函数GetCurrentThreadId()返回的DWORD (Windows- thread ID),而不是由Win32函数GetCurrentThread()返回的伪句柄(Windows- thread句柄)。

7.4 idealThreadCount

int idealThreadCount()
返回系统上可以运行的理想线程数。这是通过查询系统中实际的和逻辑的处理器内核数量来完成的。如果无法检测到处理器核数,则此函数返回1。

7.5 sleep

void msleep(unsigned long msecs)
强制当前线程休眠msecs毫秒。

如果需要等待给定条件的改变,请避免使用此函数。相反,将插槽连接到指示更改的信号或使用事件处理程序(参见QObject::event())。

注意:此函数不保证准确性。在重载条件下,应用程序的睡眠时间可能超过msec。一些操作系统可能把毫秒四舍五入到10毫秒或15毫秒。

void sleep(unsigned long secs)

void usleep(unsigned long usecs)
微秒

7.6 yieldCurrentThread

void yieldCurrentThread()
将当前线程的执行传递给另一个可运行的线程(如果有的话)。注意,由操作系统决定切换到哪个线程。

8 Protected Functions

8.1 exec

int exec()
进入事件循环并等待,直到调用exit(),返回传递给exit()的值。如果通过quit()调用exit(),则返回值为0。

该函数将在run()中调用。必须调用此函数来启动事件处理。

注意:这只能在线程本身中调用,即当它是当前线程时。

8.2 run

virtual void run()
线程的起始点。在调用start()之后,新创建的线程调用这个函数。默认实现只调用exec()。

您可以重新实现此函数以方便高级线程管理。从这个方法返回将结束线程的执行。

9 Static Protected Members

void setTerminationEnabled(bool enabled = true)
基于enabled参数启用或禁用当前线程的终止。线程必须是由QThread启动的。

当enabled为false时,终止被禁用。以后对QThread::terminate()的调用将立即返回而不生效。相反,终止将被推迟,直到启用终止。

当enabled为true时,终止被启用。以后对QThread::terminate()的调用将正常终止线程。如果终止被延迟(即QThread::terminate()在终止被禁用的情况下被调用),该函数将立即终止调用线程。注意,这个函数在这种情况下不会返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m晴朗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值