Qt经典面试题:Qt开启线程的几种方式
方法一:从QThread类派生
①创建一个类从QThread类派生
②在子线程类中重写 run 函数, 将处理操作写入该函数中
③在主线程中创建子线程对象, 启动子线程,调用start()函数
这种方法涉及到创建一个从QThread类派生的子类,并在该子类中重写run()函数。处理操作将在这个函数中进行。然后在主线程中创建子线程对象,并通过调用start()函数启动子线程。
class WorkerThread : public QThread
{Q_OBJECTvoid run() override {/* ... here is the expensive or blocking operation ... */}
};void MyObject::startWorkInAThread()
{WorkerThread *workerThread = new WorkerThread(this);connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);workerThread->start();
}
方法二:使用业务处理类
①将业务处理抽象成一个业务类, 在该类中创建一个业务处理函数
②在主线程中创建一QThread类对象
③在主线程中创建一个业务类对象
④将业务类对象移动到子线程中
⑤在主线程中启动子线程
⑥通过信号槽的方式, 执行业务类中的业务处理函数
这种方法涉及到将业务处理抽象成一个业务类,并在该类中创建一个业务处理函数。然后在主线程中创建一个QThread类对象和一个业务类对象。通过QObject::moveToThread()将业务类对象移动到子线程中,然后在主线程中启动子线程。通过信号槽的方式,执行业务类中的业务处理函数。
class Worker : public QObject
{Q_OBJECT
public slots:void doWork(const QString ¶meter) {/* ... here is the expensive or blocking operation ... */emit resultReady(result);}
signals:void resultReady(const QString &result);
};class Controller : public QObject
{Q_OBJECTQThread workerThread;
public:Controller() {Worker *worker = new Worker;worker->moveToThread(&workerThread);connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);connect(this, &Controller::operate, worker, &Worker::doWork);connect(worker, &Worker::resultReady, this, &Controller::handleResults);workerThread.start();}~Controller() {workerThread.quit();workerThread.wait();}
public slots:void handleResults(const QString &);
signals:void operate(const QString &);
};
方法三:使用QThreadPool和QRunnable
①创建一个从QRunnable类派生的类,并在该类中重写run()函数。处理操作将在这个函数中进行。
②在主线程中获取QThreadPool的全局实例,并创建一个Worker类对象。
③使用QThreadPool的start()函数来启动Worker对象的执行。
QThreadPool管理一组线程。你可以使用QThreadPool类来复用已经创建的线程,这可以避免线程创建和销毁的开销。QRunnable是一个可以在QThreadPool中运行的任务。
class Worker : public QRunnable
{void run() override{// Your code here}
};QThreadPool *pool = QThreadPool::globalInstance();
Worker *worker = new Worker();
pool->start(worker);
方法四:使用QtConcurrent
①定义一个函数或者lambda表达式,这个函数或者lambda表达式将在一个新的线程中执行。
②使用QtConcurrent::run()函数来在一个新的线程中执行这个函数或者lambda表达式。这个函数会返回一个QFuture对象。
③使用QFuture对象来查询计算的状态和结果。
QtConcurrent模块提供了一些高级函数,可以将函数调用或计算分发到多个线程中。这些函数返回一个QFuture对象,你可以使用这个对象来查询计算的状态和结果。
QFuture<int> future = QtConcurrent::run([]() -> int {// Your code herereturn result;
});
这些方法都是Qt中常见的线程处理方式,选择哪种方式取决于你的具体需求和编程风格。
多线程使用注意事项
-
业务对象,构造的时候不能指定父对象
-
子线程中不能处理ui窗口(ui相关的类)
-
子线程中只能处理一些数据相关的操作, 不能涉及窗口 除了这三条继续介绍用简短精炼的话
-
线程安全:在多线程环境中,需要确保数据的线程安全。如果多个线程访问和修改同一份数据,需要使用锁(如QMutex)或其他同步机制来防止数据竞争。
-
资源管理:线程的创建和销毁需要消耗资源,因此需要谨慎管理线程的生命周期。对于一些短期的任务,可以考虑使用线程池来复用线程。
-
错误处理:线程中的错误处理是一个复杂的问题。需要确保线程中的错误能够被正确捕获和处理,而不是导致整个程序崩溃。
-
通信:线程之间的通信通常通过信号和槽进行。需要注意的是,Qt的信号和槽机制在多线程环境中是线程安全的。
-
阻塞操作:在子线程中进行阻塞操作时,需要确保这不会影响到主线程的响应性。如果一个操作可能会花费很长时间,应该在一个单独的线程中进行。
-
优先级:可以通过设置线程的优先级来控制线程的执行顺序。但是需要注意的是,线程优先级的设置可能会受到操作系统的影响和限制。
相关文章:
Qt经典面试题:Qt开启线程的几种方式
方法一:从QThread类派生 ①创建一个类从QThread类派生 ②在子线程类中重写 run 函数, 将处理操作写入该函数中 ③在主线程中创建子线程对象, 启动子线程,调用start()函数 这种方法涉及到创建一个从QThread类派生的子类,并在该子类中重写run()函数。处理操…...

使用chartgtp写Android代码
<LinearLayout android:layout_width"match_parent" android:layout_height"match_parent" android:orientation"horizontal"> <TextView android:id"id/姓名" …...

【C++】4.jsoncpp库:jsoncpp库安装与使用入门
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍jsoncpp的使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习知识,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路&am…...

HTML、CSS、 JavaScript介绍(二)
CSS 指层叠样式表 (Cascading Style Sheets),CSS定义如何显示 HTML 元素。HTML 标签原本被设计为用于定义文档内容,样式表定义如何显示 HTML 元素,就像 HTML 中的字体标签和颜色属性所起的作用那样。样式通常保存在外部的 .css 文件中。我们只…...
高效益的淘客APP要怎么开发,需要哪些功能
现在各大淘客app都有移动端的app,但是一直不知道如何推广出去。客app想要赚钱,要思考怎么推广淘客app,推广适用于非常执行力的人。淘客app推广首要第一条,产品要好,app要好,返利要高,用户才会使…...

Java基础--->IO流(2)【常见IO模型】
文章目录 计算机角度IO操作系统IO常见的IO模型Java 中 3 种常见 IO 模型BIO(BlockingI/O)【同步阻塞IO】NIO(Non-blocking/New I/O)【非阻塞IO】IO多路复用AIO(Asynchronous I/O)【异步IO】 计算机角度IO 根…...
JavaScript let 和 const
在JavaScript中,let和const是用于声明变量的关键字。 let关键字用于声明一个块级作用域的变量。块级作用域是指在一个代码块(通常是在花括号 {} 内部)中声明的变量只在该代码块内部有效。例如: javascript function example() {…...
云原生下多集群的监控系统背景、架构设计与实现
随着云原生技术的普及,越来越多的企业开始采用多集群部署方案来提高系统的可用性和灵活性。在这种情况下,如何有效地监控多个集群的运行状态,成为了云原生架构下的一个重要问题。 多集群监控系统需要考虑以下几个方面的问题: 监…...

利用OpenCV处理图像
OpenCV是非常流行的图像处理库,下面介绍一下其对图像的基本操作。 1. 安装与环境 安装还有点儿复杂的,但百度几篇博客基本能解决,这里就不多说了。 安装好后,要在工程中使用OpenCV的头文件和库,需要在CMakeLists.tx…...
【面试实战】SpringIoC、AOP、MVC面试实战
version:1.0 文章目录 SpringSpring基础 / IoC🙎♂️面试官:举例Spring的模块?🙎♂️面试官:Spring、SpringMVC、Spring Boot关系?🙎♂️面试官:说说对SpringIoC的了解?🙎♂️面试官:什么是Spring Bean?🙎♂️面试官:Bean的作用域?🙎♂️面…...
[Redis 分布式锁 ]
目录 前言: 使用场景: 基于 Redis 实现分布式锁的详细示例: 使用示例: 依赖: Redis分布式锁控制并发访问: 前言: 记录一些小笔记 , 如果对你有帮助 那就更好了 使用场景: Redis 实现分布式锁的使用场景包括: 防止重复操作…...
如何创建Vue实例?Vue实例有哪些属性和方法
Vue实例就是Vue的实例化对象,就像你有一个iPhone,那么iPhone就是你的实例化对象。要创建Vue实例,就像你想拥有一部iPhone一样,首先要有一个设计图。 这个设计图就相当于Vue实例的options对象,你可以设置它的属性&…...

InnoDB Cluster集群Mysql Router代理层最佳实践
InnoDB Cluster 集群 & Mysql-Router 代理层 前言 Mysql是现今最常用的关系型数据库之一,高可用一直是我们对软件服务的要求。常见的Mysql高可用是主从配置,在主节点挂掉后需要依赖监控脚本进行主从切换将从节点升级,后台服务代码层面也…...

RabbitMQ系列-概念及安装
1. 消息队列 消息队列是指利用队列这种数据结构进行消息发送、缓存、接收,使得进程间能相互通信,是点对点的通信 而消息代理是对消息队列的扩展,支持对消息的路由,是发布-订阅模式的通信,消息的发送者并不清楚消息的…...
进程间通信之共享内存
进程间通信之共享内存 1.共享内存机制2.两种常用共享内存方式3.补充一下:linux中shm与shmm的区别4.IPC通信System V版本的共享内存shm5.存储映射共享I/O(mmap函数)1.共享内存机制 是允许两个或多个进程(不相关或有亲缘关系)访问同一个逻辑内存的机制。它是共享和传递数据的一…...

网络连接中的舔狗协议
舔狗网络协议 (discard protocol) 最近互联网上,“舔狗” 这个词语很火,也衍生出来很多梗(快速说出互联网 4 大舔狗!!!)。然后今天偶然间看到了一个 RFC 文档, 发现了一…...

一分钟了解乐观锁、悲观锁、共享锁、排它锁、行锁、表锁以及使用场景
大家好,我是冰点,今天给大家带来,关于MySQL中的锁的使用。 我首先提个问题,大家知道什么是 乐观锁、悲观锁、共享锁,、排它锁、行锁、表锁,以及每种锁的使用场景吗? !! 背景:最近在各…...

【C++】C++ 中的 IO 流
文章目录 一、C语言的输入输出二、什么是流三、C IO 流1、C 标准 IO 流2、C 文件 IO 流 四、stringstream 介绍 一、C语言的输入输出 在C语言中我们使用最频繁的输入输出方式是 scanf () 与 printf(): scanf():从标准输入设备 (键盘) 读取数据…...
QFuture的使用
QFuture 是 Qt 提供的一个类,用于表示异步操作的返回值或状态。异步操作指的是那些不会阻塞主线程的操作,例如文件读写、网络请求、计算等等。 在执行异步操作时,可以使用 QtConcurrent 模块提供的函数 (QFuture<T> QtConcurrent::run…...

通过dockerfile将nginx、前端和后端封装成一个镜像
1、内容如下 2、dist文件 就是vue项目的打包文件 3、jar包文件 就是springboot的打包文件 4、编写Dockerfile #引用 jdk1.8作为基础镜像,这个jdk1.8是我自己用linux版本的jdk打包的,具体操作可以看 #https://blog.csdn.net/qq_38639813/article/details/129384923中将jd…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...