QT(11)- QThread

news2024/12/27 18:47:43

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()在终止被禁用的情况下被调用),该函数将立即终止调用线程。注意,这个函数在这种情况下不会返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode力扣秋招刷题路-0037

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 37. 解数独 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字…

React hooks之useEffect《类比Vue来记忆》(二)

系列文章目录 下面是正文 文章目录系列文章目录前言一、useEffect的三种形态1.useEffect不传第二个参数代码如下&#xff1a;效果图如下&#xff1a;2.useEffect第二个参数传 []代码如下&#xff1a;效果图如下&#xff1a;3.useEffect第二个参数传 [num]代码如下&#xff1a;效…

java图

1 图基本介 1.1 为什么要有图 前面我们学了线性表和树线性表局限于一个直接前驱和一个直接后继的关系树也只能有一个直接前驱也就是父节点当我们需要表示多对多的关系时&#xff0c; 这里我们就用到了图。 1.2 图的举例说明 图是一种数据结构&#xff0c;其中结点可以具有零…

VL10 使用函数实现数据大小端转换

一、function和task都是为了模块化、结构化设计&#xff0c;主要还是将重复性的功能封装起来方便调用。可以对返回值类型和范围不进行定义&#xff0c;默认值为reg型并且位宽为1变量类型说明 比如integer ifunction(其功能同之前的module模块类似)通常是用来描述组合逻辑&#…

Hi3861编译烧录更快捷

HUAWEI DevEco Device Tool是华为面向智能设备开发者提供的一站式集成开发环境。划重点&#xff0c;DevEco Device Tool 3.1 Beta2又上新技能啦——支持纯Windows环境开发Hi3861&#xff0c;显著提升编译、烧录效率&#xff0c;同时还带来了更多实用的功能及模板&#xff0c;为…

介绍项目前期调研、需求分析阶段的工作

title: 介绍项目前期调研、需求分析阶段的工作 date: 2019-07-07 16:06:00 tags: 需求分析前期调研 categories:架构 立项阶段 所谓立项就是公司内部进行研究、讨论决定要不要做这个事情&#xff0c;通常立项分成两个大类&#xff1a; 项目立项 相对比较简单&#xff0c;需…

欧几里得度量和余弦度量的可取消生物识别方案

欧几里得度量和余弦度量的可取消生物识别方案 便捷的生物识别数据是一把双刃剑&#xff0c;在为生物识别认证系统的繁荣铺平道路的同时&#xff0c;也带来了个人隐私问题。为了缓解这种担忧&#xff0c;提出了各种生物特征模板保护方案来保护生物特征模板免于信息泄露。现有提案…

大道至简 初识springboot

参考文档&#xff1a;springboot官方中文文档 开发工具&#xff1a;IntelliJ IDEA 入门 springboot介绍 Spring Boot帮助你创建可以运行的独立的、基于Spring的生产级应用程序。 我们对Spring平台和第三方库采取了有主见的观点&#xff0c;这样你就能以最少的麻烦开始工作。 …

Service基础使用

Service简介 Service是什么 Service是一个应用组件&#xff0c;它用来在后台完成一个时间跨度比较大的工作&#xff0c;且没有关联任何界面。 Service的生命周期方法在主线程运行。 使用场景 service用于在后台完成用户指定的操作。 访问网络&#xff1b;播放音乐&#xf…

指针的步长及意义(C语言基础)

指针的步长及意义 文章目录指针的步长及意义指针变量1后偏移的字节数不同指针[解引用](https://so.csdn.net/so/search?q解引用&spm1001.2101.3001.7020)时取出的字节数不同其他例子不同类型的指针有何不同的意义指针变量1后跳跃字节数量不同解引用的时候&#xff0c;取出…

虹科方案 | 制药环境中冰箱温度记录的最佳实践——全集成温度监测系统

有效监测冰箱温度是药店、医疗中心和制药实验室的一项重要要求。保持准确的冰箱温度记录对所有储存处方药和疫苗的设施来说是必不可少的&#xff0c;但实现这一目标的最佳方法是什么&#xff1f;● 制药机构需要在特定的温度下储存疫苗和处方药&#xff0c;以保证病人的安全并确…

微信小程序-常用api

文章目录微信小程序-常用api路由wx.switchTab(Object object)wx.navigateTo(Object object)wx.navigateBack(Object object)wx.redirectTo(Object object)提示wx.showToast(Object object)wx.showModal(Object object)wx.showLoading(Object object)wx.showActionSheet(Object …

了解线程池newFixedTheadPool

什么是线程池 操作系统 能够进行运算 调度 的最小单位。线程池是一种多线程处理形式。 为什么引入线程池的概念 解决处理短时间任务时创建和销毁线程代价较大的弊端&#xff0c;可以使用线程池技术。 复用 饭店只有一个服务员和饭店有10个服务员 线程池的种类 newFixedThea…

Linux下载安装MySQL8的方式,并开放外网访问

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发&#xff08;Vue、SpringBoot和微信小程序&#xff09;、系统定制、远程技术指导。CSDN学院、蓝桥云…

软考的证书含金量高吗?

因为该考试还具有水平考试性质&#xff0c;报考任何级别不需要学历、资历条件&#xff0c;只要达到相应的专业技术水平就可以报考相应的级别。考试合格者将颁发由中华人民共和国人力资源和社会保障部、工业和信息化部用印的计算机技术与软件专业技术资格&#xff08;水平&#…

Flutter Web:图片相关及跨域问题

加载网络图片 在flutter web上也可以使用Image这个widget来加载显示图片。但是涉及到网络图片的时候就可能会出现问题&#xff0c;现象是不显示图片&#xff0c;控制台报错&#xff1a; Failed to load network image. Image URL: https://cdnimagelive.knowbox.cn/image/7841…

2023年上半年软考高项报名条件-信息系统项目管理师

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

62 序列到序列学习(seq2seq)【动手学深度学习v2】

62 序列到序列学习&#xff08;seq2seq&#xff09;【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV16g411L7FG/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 一个句子翻译到另一个句子。 seq2seq 最早…

经典网络模型系列——Swin-Transformer详细讲解与代码实现

经典网络模型系列——Swin-Transformer详细讲解与代码实现一、网路模型整体架构二、Patch Partition模块详解三、Patch Merging模块四、W-MSA详解五、SW-MSA详解masked MSA详解六、 Relative Position Bias详解七、模型详细配置参数八、重要模块代码实现&#xff1a;1、Patch P…

Android开发【金三银四】之OKhttp网络通讯socket

一、SOCKS代理 全能代理&#xff0c;就像有很多跳线的转接板&#xff0c;它只是简单地将一端的系统连接到另外一端。支持多种协议&#xff0c;包括http、ftp请求及其它类型的请求。它分socks 4 和socks 5两种类型&#xff0c;socks 4只支持TCP协议而socks 5支持TCP/UDP协议&am…