当前位置: 首页 > news >正文

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子类的类名)。

应用程序的线程称为主线程,额外创建的线程为工作线程。一般在主线程里面创建工作线程,并调用 start() 开始执行工作线程的任务。start()会在内部调用run()函数,进入工作线程的循环,在 run() 函数里调用 exit() 或 quit() 可以结束线程的事件循环,或在主线程里调用 terminate() 强制结束线程。

                                                            QThread类的主要接口
类型函数功能
       公共函数bool  isFinished ()线程是否结束
bool  isRunning ()线程是否正在运行
Priority  priority ()返回线程的优先级
void setPriority (Priority  priority)设置线程的优先级
void exit(int returnCode=0)退出事件的循环,退出码为returnCode ,0表示成功,否则表示有错误
bool wait(unsigned long time)阻止线程执行,直到线程结束(从run函数返回),或等待时间超过time毫秒
公共槽函数void  quit()退出线程的事件循环,并返回代码0,等效于exit()
void  start(Priority  priority)内部调用run()函数开始执行线程,操作系统根据priority参数进行调度终止线程的运行,但不是立即结束线程,而是等待操作系统结束线程。使用terminate()之后应使用wait()
void terminate()
 信号void  finished()在线程结束时发射此信号
void start()在线程开始执行、run()函数被调用之前发射此信号
静态公共函数int  idealThreadCount()返回系统上能运行的线程的理性个数
void  msleep(unsigned long msecs) 强制当前线程休眠msecs毫秒
void sleep(unsigned long secs)强制当前线程休眠secs秒
void  usleep(unsigned long usecs) 强制当前线程休眠uecs微秒
保护函数virtual void run()start()调用run()函数开始线程任务的执行,所以在run()函数里实现线程的任务功能
int exec()由run()函数调用,进入线程的时间循环,等待exit()退出

2.小案例

threaddlg.h
#ifndef THREADDLG_H
#define THREADDLG_H
#define  MAXSIZE 5
#include "workthread.h"
#include <QDialog>
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui { class Threaddlg; }
QT_END_NAMESPACEclass Threaddlg : public QDialog
{Q_OBJECTpublic:Threaddlg(QWidget *parent = nullptr);~Threaddlg();private:Ui::Threaddlg *ui;QPushButton  *startBtn;QPushButton  *stopBtn;QPushButton  *quitBtn;WorkThread *workThread[MAXSIZE];public  slots:void  slotStart();void  slotStop();};
#endif // THREADDLG_H

threaddlg.cpp

#include "threaddlg.h"
#include "ui_threaddlg.h"
#include<QHBoxLayout>
Threaddlg::Threaddlg(QWidget *parent): QDialog(parent), ui(new Ui::Threaddlg)
{ui->setupUi(this);setWindowTitle(QStringLiteral("线程"));startBtn=new QPushButton(QStringLiteral("线程"));stopBtn=new QPushButton(QStringLiteral("停止"));quitBtn=new QPushButton(QStringLiteral("退出"));QHBoxLayout *mainLayout=new QHBoxLayout(this);mainLayout->addWidget(startBtn);mainLayout->addWidget(stopBtn);mainLayout->addWidget(quitBtn);connect(startBtn,SIGNAL(clicked()),this,SLOT(slotStart()));connect(stopBtn,SIGNAL(clicked()),this,SLOT(slotStop()));connect(quitBtn,SIGNAL(clicked()),this,SLOT(close()));}Threaddlg::~Threaddlg()
{delete ui;
}void Threaddlg::slotStart()
{for(int i=0;i<MAXSIZE;i++){workThread[i]=new WorkThread; //创建指定数目的WorkThread线程,并将其保存在指针数组workThread中}for(int i=0;i<MAXSIZE;i++){workThread[i]->start();//调用QThread基类start函数,此函数将启动run,使线程开始真正运行}startBtn->setEnabled(false);stopBtn->setEnabled(true);
}void Threaddlg::slotStop()
{for(int i=0;i<MAXSIZE;i++){workThread[i]->terminate();//terminate函数不会立刻终止这个线程,该线程何时终止取决于操作系统的调度策略workThread[i]->wait();//使线程阻塞等待直到退出或超时}startBtn->setEnabled(true);stopBtn->setEnabled(false);
}
WorkThread.h
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
#include <QtDebug>
class WorkThread : public QThread
{
public:WorkThread();protected:void  run();
};#endif // WORKTHREAD_H

 WorkThread.cpp

 #include "workthread.h"WorkThread::WorkThread()
{}void WorkThread::run()
{while(true){for(int n=0;n<10;n++)qDebug()<<n<<n<<n<<n<<n<<n<<n;}
}

结果:

          1个线程                                                                                                           5个线程

 

 可以看出,一个线程输出是顺序打印的,5个线程也就是多线程的输出结果是乱码打印的

犯了一个很低级的错误

报错为:

原来是因为:    对了,就是clicked没有加括号

相关文章:

QT 初识多线程

1.QThread线程基础 QThread是Qt线程中有一个公共的抽象类&#xff0c;所有的线程类都是从QThread抽象类中派生的&#xff0c;需要实现QThread中的虚函数run(),通过start()函数来调用run函数。 void run&#xff08;&#xff09;函数是线程体函数&#xff0c;用于定义线程的功能…...

ubuntu修改用户名和用户密码

1.修改passwd文件 sudo gedit /etc/passwd2.修改shadow文件 sudo gedit /etc/shadow3.修改home目录下文件夹名 mv /home/原用户名/ /home/新用户名4.修改sudo权限&#xff08;修改group用户组&#xff09; sudo gedit /etc/group5.修改用户密码 sudo passwd username #修改…...

七、Linux中一些符号的含义和宿主目录的介绍

1、Linux中一些符号的含义 在Linux命令行中&#xff0c;会看到如下一些符号&#xff0c;含义如下。 符号含义. 代表当前目录..代表上一层目录&#xff0c;当前目录的父目录-代表前一个目录&#xff0c;刚才从哪个目录cd过来~代表当前用户的宿主目录/代表根目录$普通用户的命…...

Python基础语法:数据分析利器

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…...

NIO基础

一、NIO基础 Java New IO是从Java1.4版本开始引入的一个新的IO api&#xff0c;可以替代以往的标准IO&#xff0c;NIO相比原来的IO有同样的作用和目的&#xff0c;但是使用的方式完全不一样&#xff0c;NIO是面向缓冲区的&#xff0c;基于通道的IO操作&#xff0c;这也让它比传…...

npm修改为国内镜像

npm config get registry 查看下载地址&#xff0c;默认是https://registry.npmjs.org/ 这是国外的地址&#xff0c;npm下载很慢 npm config set registry https://registry.npmmirror.com/ 使用此指令&#xff0c;修改为淘宝镜像&#xff0c;输入指令后检查是否修改成功 …...

php魔术方法和反序列化漏洞

什么是反序列化漏洞&#xff1f; 漏洞形成的根本原因就是程序没有对用户输入的反序列化字符串进行检测&#xff0c;导致反序列化过程可以被恶意控制&#xff0c;进而造成代码执行、GetShell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的&#xff0c;也存在于Java、Pyth…...

依赖项的处理与层的创建与注册

依赖项的处理与层的创建与注册 依赖项的处理与层的创建与注册 新问题什么是 layer?layer 的创建与注册 与函数同时创建和绑定单独上传 layer 再绑定函数(推荐) 真正的运行时依赖 注册包的约定与平台强关联的运行时 1. 云端安装依赖2. 本地构建 Amazon Linux 2 容器环境3. 利用…...

Linux CentOS7 系统中添加用户

在linux centOS7系统中&#xff0c;添加用户是管理员的基本操作。作为学习linux系统的基本操作&#xff0c;对添加用户应该多方面了解。 添加用户的命令useradd&#xff0c;跟上用户名&#xff0c;就可以快速创建一个用户。添加一些选项&#xff0c;可以设置更人性化的用户信息…...

八、任务状态

1、任务状态简介 (1)任务状态可以简单的分为运行和非运行。 (2)非运行状态可以细分为&#xff1a;阻塞状态、暂停状态、就绪状态。 2、阻塞状态(Blocked) (1)举例说明&#xff1a;在日常生活的例子中&#xff0c;母亲在电脑前跟同事沟通时&#xff0c;如果同事一直没回复&a…...

基于python的反爬虫技术的研究设计与实现

摘 要 当下的网络是复杂的&#xff0c;网络上的信息非常的丰富&#xff0c;但也造成了大量的信息堆积&#xff0c;特别是大量的重复信息被反复的推送给用户。这是一个流量的时代&#xff0c;很多社会群体都会聚焦具备流量潜力的信息&#xff0c;从而发生蹭热度等行为来提升自己…...

msvcr120.dll放在哪里?怎么修复msvcr120.dll文件

当您在运行某些应用程序或游戏时遇到“msvcr120.dll缺失”错误时&#xff0c;这可能会影响您的使用体验。msvcr120.dll是Microsoft Visual C Redistributable的一部分&#xff0c;并且它提供了程序运行所需的运行时支持&#xff0c;今天我们来讨论一下msvcr120.dl文件缺失了要怎…...

Ubuntu搭建NFS服务

# 服务器初始化步骤 ## 查看磁盘 fdisk -l ## 格式化磁盘&#xff0c;后面的盘符注意对应关系 mkfs.ext4 /dev/sdc ## 新建文件夹 mkdir /mnt/nfs ## 挂载磁盘到创建的文件夹 echo "/dev/sdc /mnt/nfs ext4 defaults 0 0" >> /etc/fstab ## 重新挂载所有分区…...

PHP教学质量评估系统Dreamweaver开发mysql数据库web结构php编程计算机网页代码

一、源码特点 PHP教学质量评估系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 代码 https://download.csdn.net/download/qq_41221322/88301983 论文 https://down…...

ElementUI浅尝辄止15:Table 表格

用于展示多条结构类似的数据&#xff0c;可对数据进行排序、筛选、对比或其他自定义操作。 Table组件比较常用&#xff0c;常见于数据查询&#xff0c;报表页面&#xff0c;用来展示表格数据。 1.如何使用&#xff1f; //当el-table元素中注入data对象数组后&#xff0c;在el-t…...

配置LVS_DR模式以及nginx负载均衡

一、配置LVS--DR模式&#xff1a; yum install ipvsadm 配置 LVS 负载均衡服务 &#xff08; 1 &#xff09;手动添加 LVS 转发 1 &#xff09;用户访问&#xff1a; www.uolookking.com-->vip 192 .168.79.110 ##> 这个是在 DNS 配置 hzitedu 域的 DNS 记录设置 w…...

虚拟数字人直播软件实现带货功能,成为新一代直播风口!

随着短视频带货市场的不断发展&#xff0c;虚拟数字人直播技术逐渐成为热门话题。而在现如今的市场趋势下直播带货则成为了一种火热的营销方式。那么&#xff0c;虚拟数字人直播软件是否可以结合起来&#xff0c;实现无人直播带货的效果呢&#xff1f;让我们来了解一下。 灰豚数…...

01背包问题暴力解法(回溯法)和经典解法

暴力解法&#xff08;回溯法&#xff09; import java.util.Arrays; import java.util.Scanner;public class Main {private final static int N 999;public static int SumValue 0;public static int SumWeight 0;public static int OptimalValue 0;public static int O…...

K8S的CKA考试环境和题目

CKA考试这几年来虽然版本在升级&#xff0c;但题目一直没有大的变化&#xff0c;通过K8S考试的方法就是在模拟环境上反复练习&#xff0c;通过练习熟悉考试环境和考试过程中可能遇到的坑。这里姚远老师详细向大家介绍一下考试的环境和题目&#xff0c;需要详细资料的同学请在文…...

docker清理

1. 查看docker 磁盘占用 docker system df 2. 参考&#xff1a; Docker磁盘占用与清理问题_docker system prune_蓝鲸123的博客-CSDN博客...

飞书自动化开发实战:从脚本编写到事件驱动架构设计

1. 项目概述&#xff1a;飞书自动化&#xff0c;从“手动挡”到“自动驾驶”的进化 如果你每天的工作&#xff0c;有超过30%的时间是在飞书里重复着“点击-填写-发送”的枯燥操作&#xff0c;比如手动拉取数据生成日报、定时向群聊推送消息、或者根据特定条件审批流程&#xf…...

智能GUI自动化:从SAG架构到实战部署的完整指南

1. 项目概述与核心价值最近在开源社区里&#xff0c;我注意到一个挺有意思的项目&#xff0c;叫openclaw-skill-sag。乍一看这个标题&#xff0c;可能会觉得有点抽象&#xff0c;但如果你对自动化、机器人流程自动化&#xff08;RPA&#xff09;或者智能体&#xff08;Agent&am…...

Vibe Coding Playbook:从环境到心流,打造高效愉悦的编程系统

1. 项目概述&#xff1a;一个关于“氛围感编程”的实践指南最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“Vibe Coding Playbook”。乍一看这个标题&#xff0c;可能会有点摸不着头脑——“Vibe Coding”是什么&#xff1f;是某种新的编程范式吗&#xff1f;还是某种神…...

ARM Cortex-X4/X925处理器仿真模型与指令集详解

1. ARM Cortex-X4/X925处理器仿真模型概述处理器仿真模型在现代芯片设计中扮演着至关重要的角色&#xff0c;特别是在Arm架构的生态系统中。作为Arm最新一代高性能核心&#xff0c;Cortex-X4和X925的Iris仿真组件提供了完整的指令集和微架构行为建模&#xff0c;使开发者能够在…...

中鼎智能冲刺港股:年营收18.8亿 诺力股份是实控股东

雷递网 雷建平 5月16日中鼎智能&#xff08;无锡&#xff09;科技股份有限公司&#xff08;简称&#xff1a;“中鼎智能”&#xff09;日前更新招股书&#xff0c;准备在港交所上市。截至2026年3月31日止三个月&#xff0c;与上年同期相比&#xff0c;中鼎智能录得相对稳定的收…...

Camera Graph™相机拓扑图谱引擎技术白皮书

前言在数字孪生、全域感知、智能安防等领域快速发展的今天&#xff0c;多镜头协同感知已成为实现全域覆盖、精准识别、连续追踪的核心基础。然而&#xff0c;传统多相机部署模式下&#xff0c;各镜头始终处于“孤立工作”状态&#xff0c;数据互通存在壁垒、时空对齐精度不足、…...

多脉冲重复频率解速度模糊:原理、仿真与MATLAB实现

1. 脉冲雷达的速度模糊问题 雷达测速的基本原理大家都懂&#xff0c;就是通过多普勒效应计算目标速度。但实际操作中会遇到一个头疼的问题——速度模糊。这就像用卷尺量身高&#xff0c;如果身高超过卷尺长度&#xff0c;就得把几段卷尺接起来量&#xff0c;但接缝处容易出错。…...

Word分栏排版进阶:如何实现左右栏独立编辑与中英文对照排版(解决内容错乱问题)

Word分栏排版进阶&#xff1a;左右栏独立编辑与中英文对照排版实战指南 在专业文档制作中&#xff0c;双语对照排版是教师、翻译人员和外语学习者经常遇到的挑战。传统分栏功能虽然简单易用&#xff0c;但当我们需要左边显示英文原文、右边显示对应中文翻译时&#xff0c;直接分…...

Point Transformer V3 牙齿语义分割测试结果为0问题:完整调试与修复方案

Point Transformer V3 牙齿语义分割测试结果为0问题:完整调试与修复方案 摘要 Point Transformer V3(PTv3)是CVPR 2024发布的高效点云处理模型,在语义分割任务中表现出色。然而,在16类牙齿语义分割任务的测试阶段,模型输出全部为0的问题却常常困扰开发者。本文将从数据…...

基于ADT7410与ESP8266的物联网温度监测系统实战指南

1. 项目概述&#xff1a;从传感器到云端的温度监测闭环在嵌入式开发和物联网项目中&#xff0c;温度监测是一个经典且高频的需求场景。无论是实验室环境监控、智能家居的恒温控制&#xff0c;还是工业设备的状态感知&#xff0c;一个稳定、精确且能远程访问的温度数据流都是基础…...