Qt系统相关——QThread

news2024/9/24 3:22:41

文章目录

    • QThread的API
    • 使用示例
    • 客户端多线程应用场景
    • 互斥锁
      • QMutex
      • QMutexLocker
      • QReadWriteLocker、QReadLocker、QWriteLocker
    • 条件变量和信号量

QThread的API

Qt中的多线程和Linux中的线程,本质上是一个东西

Linux线程概念

Linux多线程——线程控制

Linux多线程——互斥锁

Linux多线程——生产消费者模型

QThread:

  • 要创建线程,需要创建这个类的实例
  • 创建线程时,需指明线程入口函数
  • 创建QThread的子类,重写了其中的run方法,起到指定入口函数的方式(多态)

Tips:

这种方式在C++中并不常见,相比之下std::thread直接指定回调方式更常见

因为C++比较追求性能,多态机制可能导致运行时的额外开销(查询函数表,找到对应执行函数再执行)

但是对应客户端开发,对性能的要求,并没有那么的高

API说明
run()线程入口函数
start()通过运行run()开始执行线程
(该操作是真正调用系统API创建线程)
currentThread()获取当前线程的指针
isRunning()如果线程正在运行返回true,否则返回false
sleep()、msleep()、usleep()线程休眠,单位秒/毫秒/微妙
wait()线程阻塞,功能和pthread_join类似
terminate()终止线程执行。
线程可以立即终止,也可以不终止,取决于操作系统的调用
finished()线程结束发出的信号,可通过该信号实现线程的清理工作

使用示例

基于定时器的倒计时程序

创建QThread子类:

image-20240923211212409

thread.h

#ifndef THREAD_H
#define THREAD_H

#include <QWidget>
#include<QThread>
class Thread : public QThread
{
    Q_OBJECT
public:
    Thread();

    //重写父类run方法
    void run();
signals:
    //只需写函数声明, 定义Qt自动生成
    void notify();
};

#endif // THREAD_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include"thread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void handle();

private:
    Ui::Widget *ui;
    Thread thread;
};
#endif // WIDGET_H

thread.cpp

#include "thread.h"

Thread::Thread()
{

}

void Thread::run()
{
    //针对时间进行计时,每过一秒,通过信号槽通知主线程更新界面
    for(int i = 0; i < 10; i++)
    {
        sleep(1);
        //发生信息
        emit notify();
    }
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //连接信号槽
    connect(&thread, &Thread::notify, this, &Widget::handle);

    //启动线程
    thread.start();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handle()
{
    int value = ui->lcdNumber->intValue();
    value--;
    ui->lcdNumber->display(value);
}

如果多个线程同时对界面进行修改,就会导致界面出错。

Qt直接一刀切,针对控件的任何修改,都在主线程中执行。

运行示意图:

image-20240923212827943

客户端多线程应用场景

在服务器开发的角度,多线程主要是充分利用多核CPU的计算资源,达到更高的效率。

而对于客户端,对效率要求并不是特别高,如果追求效率,把CPU计算资源吃完,会导致系统卡顿,这用户体验是很差的。

在客户端中,多线程主要是用于一些耗时的等待IO的操作,避免主线程卡死。

比如说客户端向服务端上传/下载较大的文件

这种密集的IO操作会使程序被系统阻塞挂起,一旦进程被挂起了,此时用户的操作就无法响应了。

因此使用单独的线程来处理这种密集的IO操作,就算挂起,也是挂起的这个线程,并不会影响主线程。

互斥锁

QMutex

谈到线程,必定绕不开线程安全问题,最通用的手段就是加锁,QMutex类就是Qt封装的互斥锁。

image-20240923215302391

上面这种情况就是线程安全问题,采取加锁,让线程串行执行

锁也是公共区的,只有一把锁

image-20240923215537861

QMutexLocker

C++11引入了std::lock_guard,智能锁RAII机制,这样能避免抛出异常或者忘记释放锁导致的问题。

Qt参考过来了,叫做QMutexLocker

image-20240923220111369

Tips:

Qt的锁和C++的锁,本质上都是封装系统提供的锁

虽然可以用C++的锁锁住Qt的线程,但是不建议。

QReadWriteLocker、QReadLocker、QWriteLocker

  • QReadWriteLocker读写锁,用于控制读和写的并发访问
  • QReadLocker用于读操作上锁,允许多个线程共享资源
  • QWriteLocker用于写操作上锁,一次允许一个线程写数据

条件变量和信号量

Qt当中的条件变量和信号量,与Linux当中的概念一模一样,只不过是接口不一样而已。

多个线程的调度是无序的,为了一定程度干预执行顺序,引入条件变量。

QWaitCondition

  • wait等待
  • wake唤醒
  • wakeAll唤醒全部

QSemaphore

  • acquire获取信号量
  • release释放信号量

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

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

相关文章

EEPROM手册阅读笔记

目录 一、特征描述二、功能描述三、总线特性四、设备寻址五、写入操作1.字节写入2.页写入 六、读取操作1.当前地址读取2.随机读取3.顺序读取 一、特征描述 1.Microchip Technology Inc. 24AA04/24LC04B &#xff08;24XX04*&#xff09; 是一款 4 Kbit 电气可擦除 PROM。该器件…

【4】AT32F437 OpenHarmony轻量系统移植教程(1)

开源地址&#xff1a;https://gitee.com/AT32437_OpenHarmony 1.学习本文档的意义 1.学习移植OpenHarmony轻量系统到AT32全系列mcu上&#xff0c;本文档移植的具体型号为AT32F437ZMT7 2.学习OpenHarmony轻量系统开发 2.移植前的准备工作 1.移植之前必须要先熟悉AT-START-F…

HTTP协议:发展、请求响应、状态码 等

文章目录 HTTP发展历程HTTP请求URL和URIHTTP协议版本HTTP请求方法GET 和 POST 区别HTTP状态码HTTP 请求与响应报文HTTP 请求流程 HTTP 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在…

SAP-ABAP消息号 AD857

激活表时报错 返回表&#xff0c;找到报错的字段 维护参考表和字段

免费!大厂太卷了,又一款AI对口型神器,让照片开口说话唱歌,吊打阿里EMO?(附保姆级教程)

大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~&#xff08;AI资料点文末卡片自取&#xff09; 之前分享了一款…

【小白向】怎么去除视频水印?HitPaw帮你轻松解决

序言 HitPaw是一款优秀的去除视频水印的工具。 特点&#xff1a;不仅仅能够去除图片、视频里的固定水印&#xff0c;还能去除移动水印。 尤其是它的AI去水印功能&#xff0c;效果非常好。 极简使用教程 下载安装 HitPaw需要在电脑上安装软件才能使用。 支持Windows系统和…

【AIGC】ChatGPT RAG提取文档内容,高效制作PPT、论文

目录 一、理解 RAG 技术 二、利用 ChatGPT 的 RAG 技术提取文档内容 三、高效制作 PPT 四、高效撰写论文 五、最佳实践与建议 六、工具推荐 随着人工智能生成内容&#xff08;AIGC&#xff09;的快速发展&#xff0c;利用先进的技术工具如 ChatGPT 的 RAG&#xff08;Ret…

kismet和war driving具体准备(仅供无线安全学习)

war driving准备 一台笔记本 一个最好是双频的网卡&#xff0c;单频搜集信号少 我自己买的是http://e.tb.cn/h.grI4EmkDLOqQXHG?tkKZ5g3RVeH6f 如果经济条件允许可以去买大功率天线&#xff08;我买的车载的 大概40db这样子 范围广&#xff09; http://e.tb.cn/h.grCM0CQ6L…

YOLOv5-水印检测

简介&#xff1a; YOLOv5在YOLOv4算法的基础上做了进一步的改进&#xff0c;检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较与分析&#xff0c;但是YOLOv5在COCO数据集上面的测试效果还是挺不错的。 YOLOv5是一种单阶段目标检测算法&#xff0c;该算…

教材改版难道是假的?!24下半年软考怎么还是用旧版?何时启用新教材?

之前一直有消息说软考有几个科目的教材要改版&#xff0c;导致不少打算报名2024年下半年软考的同学都在担心是否会影响考试…… 但一直到现在都没看到有新教材出版的消息&#xff0c;所以很多人怀疑之前教材改版的消息是不是假的&#xff0c;要不然怎么还在用旧版教材…… 那…

C++11新特性和扩展(1)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 C11新特性和扩展 收录于专栏 [C进阶学习] 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1.C11简介 2. 列表初始…

Oracle 数据库安装和配置指南

目录 1. 什么是Oracle数据库&#xff1f; 2. 安装前的准备工作 2.1 硬件要求 2.2 软件要求 2.3 下载Oracle安装包 3. Oracle数据库的安装步骤 3.1 Windows系统安装步骤 3.2 Linux系统安装步骤 4. 配置Oracle数据库 4.1 设置环境变量&#xff08;Linux&#xff09; 4.…

828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Halo博客平台

828华为云征文 | 云服务器Flexus X实例&#xff0c;Docker集成搭建Halo博客平台 Halo博客平台是一款基于Java的开源博客系统&#xff0c;以其简单易用、功能强大、美观大方等特点而受到广泛欢迎&#xff0c;采用了多种先进的技术框架&#xff0c;包括Freemarker模板引擎、Vue.j…

项目总结,路径匹配的业务逻辑

redisHelper.addzset(HitchConstants.STOKE_GEO_ZSET_PREFIX,hitchGeoBo.getTargetID()&#xff08;乘客ID&#xff09;,stroke.getId()->(司机的ID&#xff09;,getscore(hitchGeoBo); 如果他不这样乘客这里存储司机的ID,我们会发现假如再来一个司机&#xff0c;他是无法获…

通过 LabVIEW 正则表达式读取数值(整数或小数)

在LabVIEW开发中&#xff0c;字符串处理是一个非常常见的需求&#xff0c;尤其是在处理包含复杂格式的数字时。本文通过一个具体的例子来说明如何利用 Match Regular Expression Function 和 Match Pattern Function 读取并解析字符串中的数字&#xff0c;并重点探讨这两个函数…

书生·浦语作业集合

目录&#xff1a; 1. Linux基础知识 2.python基础知识 3.Git基础知识 4.书生大模型全链路开源体系 1.1-Linux基础知识 配置环境后&#xff0c;运行 hello_word.py 在本地终端中进行端口映射 映射成功后&#xff0c;访问 127.0.0.1&#xff1a;7860 1.2-python基础知识 任务…

【Python】生成dataframe的测试样例,用于测试一个或者多个dataframe

我们在处理dataframe测试时&#xff0c;发现&#xff0c;总需要重新构造一个新的dataframe&#xff0c;每次想找个现成的就想抓狂。 所以&#xff0c;为了方便随用随拿&#xff0c;我在这里直接保存一个直接生成dataframe 的方法。 1. 生成一个随机dataframe的方法&#xff1…

2024/9/19 Notes

1. MODULE_IMPORT_NS 当LINUX_KERNEL_CODE > KERNEL_VERSION(5,4,0)&#xff0c; linux引入了namespace来控制内核中symbol引用范围。 比如跟USB Storage相关的一些函数&#xff0c;我们可以直接使用EXPORT_SYMBOL,使所有模块可以可用&#xff0c;也可以EXPORT_SYMBOL_NS&…

Leetcode 除自身以外数组的乘积

class Solution {public int[] productExceptSelf(int[] nums) {int length nums.length;//一维数组 answer[]存储最终的结果//首先从左往右记录乘积&#xff0c;暂时存储到一维数组 answer[] 中int[] answer new int[length];//先从左往右, 由于由于第一个元素左边没有元素&…

如何在算家云搭建RVC-WebUI(语音转换)

一、Retrieval-based-Voice-Conversion-WebUI简介 Retrieval-based-Voice-Conversion-WebUI&#xff08;简称 RVC&#xff09;模型是一个基于 VITS&#xff08;Variational Inference with adversarial learning for end-to-end Text-to-Speech&#xff09;的简单易用的语音转…