QT多线程应用及代码示例

一.多线程的原理和功能

1.多线程(multithreading)是指从软件或者硬件上实现多个线程并发执行的技术。

2.多线程的功能和作用主要包括:

提高程序的并发性和效率:多线程可以同时执行多个任务,不同的线程可以同时读写不同的数据,从而避免了线程之间的阻塞等待,提高了程序的效率和响应速度。

解决负载均衡问题,充分利用CPU的资源:通过多线程,可以同时完成多件事情而互不干扰,提高cpu的使用效率。

异步处理:将程序中占据时间长的任务放到后台去处理,如图片、视频的下载,从而提高用户体验。

发挥多核处理器的优势:通过并发执行,让系统运行的更快、更流畅。

3.多线程程序缺点:

线程之间的共享资源会引发竞争条件,造成数据不一致问题,需要使用同步机制来解决。同时,多线程程序也会增加程序的复杂度和调试难度,需要谨慎设计和维护。

二.QT中的多线程

1.QThread线程基础

    QThread是Qt线程中有一个公共的抽象类,所有的线程类都是从QThread抽象类中派生的,需要实现QThread中的虚函数run(),通过start()函数来调用run函数。

    void run()函数是线程体函数,用于定义线程的功能。

    void start()函数是启动函数,用于将线程入口地址设置为run函数。

    void terminate()函数用于强制结束线程,不保证数据完整性和资源释放。

    QCoreApplication::exec()总是在主线程(执行main()的线程)中被调用,不能从一个QThread中调用。在GUI程序中,主线程也称为GUI线程,是唯一允许执行GUI相关操作的线程。另外,必须在创建一个QThread前创建QApplication(or QCoreApplication)对象。

    当线程启动和结束时,QThread会发送信号started()和finished(),可以使用isFinished()和isRunning()来查询线程的状态。

    从Qt4.8起,可以释放运行刚刚结束的线程对象,通过连接finished()信号到QObject::deleteLater()槽。

    使用wait()来阻塞调用的线程,直到其它线程执行完毕(或者直到指定的时间过去)。

    静态函数currentThreadId()和currentThread()返回标识当前正在执行的线程。前者返回线程的ID,后者返回一个线程指针。

    要设置线程的名称,可以在启动线程之前调用setObjectName()。如果不调用setObjectName(),线程的名称将是线程对象的运行时类型(QThread子类的类名)。

2.线程的优先级

 QThread线程总共有8个优先级

 QThread::IdlePriority     0 scheduled only when no other threads are running.

 QThread::LowestPriority  1 scheduled less often than LowPriority.

 QThread::LowPriority     2 scheduled less often than NormalPriority.

 QThread::NormalPriority  3 the default priority of the operating system.

 QThread::HighPriority    4 scheduled more often than NormalPriority.

 QThread::HighestPriority  5 scheduled more often than HighPriority.

 QThread::TimeCriticalPriority  6 scheduled as often as possible.

  QThread::InheritPriority    7 use the same priority as the creating thread. This is the default.

3.void setPriority(Priority priority)

    设置正在运行线程的优先级。如果线程没有运行,此函数不执行任何操作并立即返回。使用的start()来启动一个线程具有特定的优先级。优先级参数可以是QThread::Priority枚举除InheritPriortyd的任何值。

4.线程的创建

  void start ( Priority priority = InheritPriority )

  启动线程执行,启动后会发出started ()信号

5.线程的执行

int exec() [protected]

  进入事件循环并等待直到调用exit(),返回值是通过调用exit()来获得,如果调用成功则返回0。

void run() [virtual protected]

  线程的起点,在调用start()之后,新创建的线程就会调用run函数,默认实现调用exec(),大多数需要重新实现run函数,便于管理自己的线程。run函数返回时,线程的执行将结束。

6.线程的退出

void quit();

通知线程事件循环退出,返回0表示成功,相当于调用了QThread::exit(0)。

void exit ( int returnCode = 0 );

调用exit后,thread将退出event loop,并从exec返回,exec的返回值就是returnCode。通常returnCode=0表示成功,其他值表示失败。

void terminate ();

  结束线程,线程是否立即终止取决于操作系统。

  线程被终止时,所有等待该线程Finished的线程都将被唤醒。

  terminate是否调用取决于setTerminationEnabled ( bool enabled = true )开关。

  void requestInterruption()

  请求线程的中断。请求是咨询意见并且取决于线程上运行的代码,来决定是否及如何执行这样的请求。此函数不停止线程上运行的任何事件循环,并且在任何情况下都不会终止它。

7.线程的等待

bool wait ( unsigned long time = ULONG_MAX )

  线程将会被阻塞,等待time毫秒,如果线程退出,则wait会返回。Wait函数解决多线程在执行时序上的依赖。

void msleep ( unsigned long msecs )

void sleep ( unsigned long secs )

void usleep ( unsigned long usecs )

sleep()、msleep()、usleep()允许秒,毫秒和微秒来区分,但在Qt5.0中被设为public。

一般情况下,wait()和sleep()函数应该不需要,因为Qt是一个事件驱动型框架。考虑监听finished()信号来取代wait(),使用QTimer来取代sleep()。

8.线程的状态

bool isFinished () const  线程是否已经退出

bool isRunning () const   线程是否处于运行状态

9.线程的属性

Priority priority () const

void setPriority ( Priority priority )

uint stackSize () const

void setStackSize ( uint stackSize )

void setTerminationEnabled ( bool enabled = true ) 设置是否响应terminate()函数

三.代码示例

  1. mythread.h

#ifndef MYTHREAD_H

#define MYTHREAD_H

#include <QThread>

//class QThread;

class QString;

class MyThread : public QThread

{

public:

    MyThread();

    void setMessage(const QString &message);

    void stop();

protected:

    void run();

private:

    QString m_MessageStr;

    volatile bool m_Stopped;

};

#endif // MYTHREAD_H

2.mythread.cpp

#include "mythread.h"

#include <QDebug>

MyThread::MyThread()

{

    m_Stopped = false;

}

void MyThread::setMessage(const QString &message)

{

    m_MessageStr = message;

}

void MyThread::stop()

{

    m_Stopped = true;

}

void MyThread::run()

{

    while(!m_Stopped)

    {

        qDebug()<<m_MessageStr;

        msleep(500);

    }

    m_Stopped = false;

}

3.threaddialog.h

#ifndef THREADDIALOG_H

#define THREADDIALOG_H

#include <QMainWindow>

#include <QDialog>

#include <QPushButton>

#include "mythread.h"

class ThreadDialog : public QDialog

{

    Q_OBJECT

public:

    ThreadDialog(QWidget *parent = 0);

    ~ThreadDialog();

protected:

    void closeEvent(QCloseEvent *event);

private slots:

    void startOrStopThreadA();

    void startOrStopThreadB();

private:

   MyThread m_ThreadA;

   MyThread m_ThreadB;

   QPushButton *m_ThreadAButton;

   QPushButton *m_ThreadBButton;

   QPushButton *m_QuitButton;

};

#endif // THREADDIALOG_H

4.threaddialog.cpp

#include "threaddialog.h"

#include <QHBoxLayout>

#include <QPushButton>

#include <QCloseEvent>

#include <QDebug>

ThreadDialog::ThreadDialog(QWidget *parent)

    : QDialog(parent)

{

    m_ThreadA.setMessage("A");

    m_ThreadB.setMessage("B");

    m_ThreadAButton = new QPushButton;

    m_ThreadAButton->setText("Sart A");

    m_ThreadBButton = new QPushButton;

    m_ThreadBButton->setText(tr("Start B"));

    m_QuitButton = new QPushButton;

    m_QuitButton->setText(tr("Quit"));

    m_QuitButton->setDefault(true);

    connect(m_ThreadAButton,SIGNAL(clicked(bool)),SLOT(startOrStopThreadA()));

    connect(m_ThreadBButton,SIGNAL(clicked(bool)),SLOT(startOrStopThreadB()));

    connect(m_QuitButton,SIGNAL(clicked(bool)),SLOT(close()));

    QHBoxLayout *hLayout = new QHBoxLayout(this);

    hLayout->addWidget(m_ThreadAButton);

    hLayout->addWidget(m_ThreadBButton);

    hLayout->addWidget(m_QuitButton);

    setLayout(hLayout);

    setWindowTitle(tr("Thread"));

}

ThreadDialog::~ThreadDialog()

{

}

void ThreadDialog::closeEvent(QCloseEvent *event)

{

    m_ThreadA.stop();

    m_ThreadB.stop();

    m_ThreadA.wait();

    m_ThreadB.wait();

    event->accept();

}

void ThreadDialog::startOrStopThreadA()

{

    if(m_ThreadA.isRunning())

    {

        m_ThreadA.stop();

        m_ThreadAButton->setText(tr("Start A"));

        qDebug()<<QString::fromLocal8Bit("线程停止");

    }

    else

    {

        m_ThreadA.start();

        m_ThreadAButton->setText(tr("Stop A"));

    }

}

void ThreadDialog::startOrStopThreadB()

{

    if(m_ThreadB.isRunning())

    {

        m_ThreadB.stop();

        m_ThreadBButton->setText(tr("Start B"));

        qDebug()<<QString::fromLocal8Bit("线程停止");

    }

    else

    {

        m_ThreadB.start();

        m_ThreadBButton->setText(tr("Stop B"));

    }

}

完整代码工程可在博客资源中下载:

https://download.csdn.net/download/xieliru/88845664?spm=1001.2014.3001.5501

4.运行结果

点击Start A按钮开始打印字符“A”,同时按钮显示Stop A;点击Start B按钮开始打印字符“B”,同时按钮显示Stop B;

点击Stop A按钮停止字符“A”打印,点击Stop B按钮停止字符“B”打印,点击Quit按钮退出Tread窗体。

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

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

相关文章

腾讯云助力酒店IT系统上云,实现出海业务的双重优势

潮起潮涌&#xff0c;随着时代浪潮的翻涌&#xff0c;生活处处可见是巨大的变化&#xff0c;衣食住行都有了更多更大的需求&#xff0c;出门旅游观赏当地风景品尝特色美食的前提是要住好&#xff0c;只有休息好了才有更多的精力去游玩。酒店系统的升级上云让登记变得更加便捷&a…

【机器学习笔记】13 降维

降维概述 维数灾难 维数灾难(Curse of Dimensionality)&#xff1a;通常是指在涉及到向量的计算的问题中&#xff0c;随着维数的增加&#xff0c;计算量呈指数倍增长的一种现象。在很多机器学习问题中&#xff0c;训练集中的每条数据经常伴随着上千、甚至上万个特征。要处理这…

【Linux】git操作 - gitee

1.使用 git 命令行 安装 git yum install git 2.使用gitee 注册账户 工作台 - Gitee.com 进入gitee&#xff0c;根据提示注册并登录 新建仓库 仓库名称仓库简介初始换仓库 3.Linux-git操作 进入仓库&#xff0c;选择“克隆/下载” 复制下面的两行命令进行git配置 然后将仓库clo…

教师专业发展的五个阶段

每当人们谈论教师&#xff0c;总会联想到“传道授业解惑”的崇高形象。但教师的专业成长&#xff0c;绝非一蹴而就。今天&#xff0c;就让我们一起探秘教师专业发展的五个阶段&#xff0c;看看一位普通教师是如何历练成为教育行家的。 阶段一&#xff1a;新手摸索期 初入教育行…

走进科学系列之遭遇鬼打墙的OUTLOOK

网管小贾 / sysadm.cc 正值春运&#xff0c;车站里熙熙攘攘、人头攒动。 鲍勃和约瑟夫正在候车室&#xff0c;等待检票。 “嗨&#xff01;约瑟夫&#xff01;快来看看&#xff0c;我的电脑出问题了&#xff01;” “得了吧&#xff0c;马上就要检票上车了&#xff0c;你就不…

调用接口时不时出现 Error: socket hang up

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 今天采用golang创建了一个http服务&#xff0c;准备对若干接口进行测试。 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 在测试第一个接口时&#xff0c;发现采用postman调用接口…

Ansible yum模块 主要用于软件安装

目录 选项 实例 安装一个tree实例卸载一个 tree 选项 name   #所安装的包的名称 state  #present—>安装&#xff0c; latest—>安装最新的, absent—> 卸载软件。 update_cache  #强制更新yum的缓存 conf_file  #指定远程yum安装时所依赖的配置文件&…

5G车载路由器引领无人驾驶车联网应用

随着无人驾驶技术的不断发展&#xff0c;车联网正逐渐成为实现智能交通的重要组成部分。5G车载路由器将在车联网的应用中起到至关重要的作用&#xff0c;它能够满足无人驾驶应用的低时延、高速率和实时控制等需求&#xff0c;进一步推动无人驾驶车联网技术。 5G路由器具备低时延…

从 AGP 4.1.2 到 7.5.1——XmlParser、GPathResult、QName 过时

新年首发&#xff0c; 去年的问题&#xff0c;今年解决~ 问题 & 排查 1: Task failed with an exception. ----------- * What went wrong: Execution failed for task :app:processCommonReleaseManifest. > org.xml.sax.SAXParseException; lineNumber: 1; columnNu…

【申请体验Sora】OpenAI Red Teaming Network application

网址&#xff1a;https://openai.com/form/red-teaming-network 使用Gmail &#xff0c; 国家选美国 两个问题&#xff1a; Why are you interested in joining the OpenAI Red Teaming Network? I’m eager to experience the powerful allure of Sora, which I believe wi…

postgresql 文件结构(一) 数据库、表对应的文件

1、问题 甲方要求提供数据库数据量大小&#xff0c;由于各个业务数据库共用一个postgres&#xff0c;因此想把每个数据库占用的空间都统计一下。 2、查找物理存储文件目录 如下图所示&#xff0c;可以查询表、库的物理存储文件名称 -- 查询表对应的文件 select oid,relname…

leetcode 01背包问题

典型的01背包问题可以暴力求解&#xff0c;直接将所有可能全部遍历然后挑选符合条件的即可&#xff0c;但这样时间复杂度过高&#xff0c;有2的n次方。 所以我们在这里采用动态规划的方式来做&#xff0c;并且&#xff0c;我们可以采用二维数组或者一维数组来做。 二维数组&a…

供水管网管道爆管事故发生原因及控制措施

经济的快速发展及城镇化的不断推进使得我国的城镇数量及规模都在不断地扩大。供水系统是城镇基础设施中 的重要的一环。现今在我国各城市中已经建立了相对完善的城市供水管网体系。但是在供水管网运行过程中爆管问题时 有发生&#xff0c;从而对城市用水的正常供应以及民众的正…

Redis 缓存(Cache)

什么是缓存 缓存(cache)是计算机中的一个经典的概念在很多场景中都会涉及到。 核心思路就是把一些常用的数据放到触手可及(访问速度更快)的地方&#xff0c;方便随时读取。 这里所说的“触手可及”是个相对的概念 我们知道&#xff0c;对于硬件的访问速度来说&#xff0c;通常…

vue3实现瀑布流布局组件

先看效果图 直接上代码 utils.js // 用于模拟接口请求 export const getRemoteData (data 获取数据, time 2000) > {return new Promise((resolve) > {setTimeout(() > {console.log(模拟获取接口数据, data)resolve(data)}, time)}) }// 获取数组随机项 export…

给label-studio 配置sam(segment anything)ml 记录

给label-studio 配置sam&#xff08;segment anything&#xff09;ml 后端记录 配置ml后台下载代码下载模型文件创建环境模型转换后端服务启动 配置label-studio 前端配置模型后端连接配置标注模板标注界面使用 参考链接 配置ml后台 下载代码 git clone https://github.com/H…

AT24C02(I2C总线)通信的学习

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、存储器介绍二、AT24C02芯片二、I2C总线I2C电路规范I2C时序结构I2C数据帧AT24C02数据帧 总结 前言 学习AT24C02(I2C总线)芯片 一、存储器介绍 RAM&#xf…

QT-地形3D

QT-地形3D 一、 演示效果二、关键程序三、下载链接 一、 演示效果 二、关键程序 #include "ShaderProgram.h"namespace t3d::core {void ShaderProgram::init() {initializeOpenGLFunctions();loadShaders(); }void ShaderProgram::addShader(const QString &fil…

计算机二级C语言的注意事项及相应真题-5-程序修改

目录 41.累加链表结点数据域中的数据作为函数值返回42.根据整型形参m&#xff0c;计算如下公式的值43.删除数列中值为x的元素44.从N个字符串中找出最长的那个串&#xff0c;并将其地址作为函数值返回45.将两个长度相等的纯数字字符串当作两个加数&#xff0c;求其代表的数值之和…

欢迎来到IT时代----盘点曾经爆火全网的计算机电影

计算机专业必看的几部电影 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨头的创业之路&#xff0c;《源代码》带你穿越时间解救世界&#xff0c;这…