详解Qt多线程(包含:什么是CPU,单核处理器和多核处理器,举餐厅和QQ音乐的例子详解进程和线程,Qt多线程案例)

目录

  • 一.什么是CPU?
  • 二.单核处理器与多核处理器
  • 三.什么是进程和线程?
    • 3.1 定义
    • 3.2 以餐厅为例子解释进程和线程
    • 3.2 以QQ音乐为例子,解释QQ音乐里面的进程和线程
  • 四.Qt中的多线程
  • 五.Qt多线程案例
    • 任务描述
    • 案例演示
    • 设置显示内容的字体大小和位置
    • 运行
    • 创建一个线程类
    • mywork.h
    • mywork.cpp
    • widget.h
    • widget.cpp
    • 问题:当使用对按钮右键创建的槽函数执行doWork时,主线程和子线程是同一个。
  • 参考链接

一.什么是CPU?

在这里插入图片描述

CPU(中央处理器)是计算机的核心组件,它内部包含了多个功能单元和寄存器,用于执行各种指令和完成计算任务。以下是CPU内部的一些主要部分:

  1. 控制单元(Control Unit): 控制单元负责解释和执行计算机程序中的指令。它从内存中读取指令,对指令进行解码,并控制其他部分执行相应的操作。

  2. 算术逻辑单元(Arithmetic Logic Unit,ALU): ALU执行各种算术和逻辑运算,包括加法、减法、乘法、除法等数学运算,以及逻辑运算如与、或、非等。

  3. 寄存器(Registers): 寄存器是用于存储临时数据的高速存储单元。CPU包含多个寄存器,其中包括通用寄存器、数据寄存器、地址寄存器等。寄存器的使用可以提高数据访问速度。

  4. 时钟和定时器(Clock and Timers): 时钟是CPU的心脏,通过时钟信号来同步各个部件的工作。定时器用于测量时间,处理时钟周期。

  5. 缓存(Cache): 缓存是一种高速临时存储,用于存放频繁访问的数据和指令,以提高访问速度。CPU通常包含多级缓存,包括一级缓存(L1 Cache)和二级缓存(L2 Cache)等。

  6. 总线接口(Bus Interface): 总线接口负责与计算机的其他部分进行通信,包括内存、输入输出设备等。它通过数据总线、地址总线和控制总线传输信息。

  7. 指令寄存器(Instruction Register,IR): 存储当前正在执行的指令,控制单元从中读取指令进行解码和执行。

  8. 程序计数器(Program Counter,PC): 存储下一条要执行的指令的地址,以保持程序的顺序执行。

这些部分协同工作,使得CPU能够有效地执行各种计算和控制任务。不同的CPU架构和制造商可能会有一些额外或不同的部分,但这些是CPU内部常见的组成部分。

二.单核处理器与多核处理器

一个处理器(CPU)拥有的运算核心的数量,可以区别CPU是单核还是多核。

同一时刻,CPU的每个核心都可以运行1个线程。单核和多核CPU的区别就是同一时刻可以运行几个线程,单核CPU只能运行一个,N核可以运行N个

值得一提的是,单核CPU也可以“同时”运行多个线程。不过这个“同时”只是一种假象,因为本质上单核CPU不能同时运行多线程。它的运行原理便是前文提到的CPU调度,在不同时间片内运行不同线程,由于每个时间片很短所以看起来是多个线程同时进行的,这也是所谓的并发。

三.什么是进程和线程?

3.1 定义

什么是进程?

进程(Process)是操作系统中的一个执行单位,它包含了程序代码、数据以及进程所需的系统资源(如内存、文件等),是一个独立的、运行中的程序实体。每个进程都有自己的独立内存空间,因此多个进程之间互不干扰。在现代操作系统中,每个进程都有一个唯一的进程标识符(PID),用于操作系统进行进程管理和调度。

什么是线程?

线程是操作系统能够进行运算调度的最小单位。一个线程包括了指令、寄存器和栈等信息。一个进程可以包含多个线程,这些线程共享进程的资源,但拥有各自的独立执行流。

3.2 以餐厅为例子解释进程和线程

一个餐厅是一个进程,厨师是一个线程,服务员是另一个线程。让餐厅在炒饭的同时,还可以服务客人。

具体如下:

1. 进程(Process):

想象一家餐馆,餐馆就是一个进程。在这个餐馆里,有独立的厨房、服务员、顾客等。每个进程是一个独立的执行环境,有自己的内存空间、资源、代码等。就像每家餐馆有自己的厨房、餐具和服务。

  • 例子: 一家餐馆可以同时为多桌客人提供服务,每桌客人独立享受他们的用餐体验,互不影响。如果一个桌子上的服务出了问题,其他桌子的服务仍然可以继续。

2. 线程(Thread):

现在,我们把餐馆的工作人员看作线程。在一个餐馆中,有多个工作人员,比如厨师、服务员等。每个线程负责执行不同的任务,但它们共享餐馆的资源,比如厨房、库存等。

  • 例子: 厨师和服务员是餐馆的两个线程。厨师负责烹饪食物,服务员负责上菜和为客人提供服务。这两个线程协同工作,共同维护餐馆的正常运作。

3. 多线程:

多线程就像在同一个餐馆里有多个工作人员(线程),它们可以并行执行不同的任务,提高工作效率。

  • 例子: 当有多个服务员为不同的桌子服务时,如果其中一个服务员忙于为一桌客人点菜,其他服务员仍然可以为其他桌子提供服务,使整个餐馆更高效。

总结:

  • 进程: 相当于一个完整的餐馆,拥有独立的资源和环境。

  • 线程: 相当于餐馆里的工作人员,共享餐馆的资源,协同完成任务。

  • 多线程: 相当于在同一个餐馆里有多个工作人员,可以并行执行任务,提高效率。

3.2 以QQ音乐为例子,解释QQ音乐里面的进程和线程

启动QQ音乐,系统会给QQ音乐创建一个进程,这个进程包含QQ音乐的代码,数据,内存等。
播放音乐是一个线程,界面的刷新也是一个线程。因此刷新界面和播放音乐可以同时进行。

详细内容如下:

  1. 进程(Process): 在计算机中,进程是程序的一次执行过程。当你启动QQ音乐软件时,操作系统会为QQ音乐创建一个独立的进程。这个进程包含了QQ音乐的代码、数据、内存等资源。不同的应用程序通常在不同的进程中运行,相互之间不会直接影响

  2. 线程(Thread): 线程是进程内的一个独立执行单元。在QQ音乐的进程中,可能会有多个线程同时执行。每个线程负责处理不同的任务,比如一个线程用于播放音乐,另一个用于界面的更新,等等。线程之间可以共享进程的资源,但它们有自己的执行上下文和状态。

在QQ音乐的运行过程中,进程和线程的关系可以理解为:

  • 一个进程(QQ音乐的进程): 包含了QQ音乐软件的全部资源,是一个独立运行的程序实例。

  • 多个线程: 在该进程内,可能有多个线程并发执行,每个线程负责不同的任务,比如负责播放音乐、更新用户界面等。

这样的设计有助于提高程序的并发性和响应性。不同的线程可以同时执行,使得在播放音乐的同时,界面仍然可以保持响应。然而,需要注意线程之间的协同和同步,以避免竞争条件和其他并发问题。

四.Qt中的多线程

默认的线程在Qt中是窗口线程,也叫主线程,负责窗口事件处理或窗口控件数据的更新。
子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理。
主线程和子线程之间如果要进行数据的传递,需要使用Qt中的信号槽机制。

五.Qt多线程案例

任务描述

用一个窗口显示从0-1千万。
问题:程序在从0数到1千万时,窗口无响应,无法移动窗口。等数到1千万时窗口才恢复正常。这是由于主线程在数数时无法刷新窗口造成的。
解决方法:需要主线程显示数字,子线程进行数数。

案例演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

设置显示内容的字体大小和位置

在这里插入图片描述
在这里插入图片描述

运行

发现程序在进行01千万的运算时,无法拖动窗口界面,甚至窗口卡顿。
这是因为只有一个线程的原因,该线程进行从0到一千万的运行,无法刷新窗口界面。

在这里插入图片描述

创建一个线程类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

mywork.h

#ifndef MYWORK_H
#define MYWORK_H#include <QObject>class MyWork : public QObject
{Q_OBJECT //Q_OBJECT 宏用于标记一个类,使其能够使用Qt的元对象系统,如信号与槽、动态属性等。
public:explicit MyWork(QObject *parent = nullptr);void doWork();signals:void curNumber(int num); //自定义信号,传递数据
};#endif // MYWORK_H

mywork.cpp

#include "mywork.h"
#include <QThread>
#include <QDebug>MyWork::MyWork(QObject *parent) : QObject(parent)
{}void MyWork::doWork()
{qDebug()<<"当前线程对象的地址:"<<QThread::currentThread();int num=0;while (1){emit curNumber(num++); // 发送信号,信号内容是num++if(num == 10000000){break;}QThread::usleep(1); // 这个函数的作用是让当前线程休眠指定的微秒数,让数字数的不那么快。使用线程休眠时需要注意不要在主线程(UI 线程)中调用,以免造成界面卡顿。}qDebug()<<"run()执行完毕,子线程退出...";
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mywork.h"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:
//    void on_pushButton_clicked();void showNum(int num); //用来展示数字private:Ui::Widget *ui;MyWork* worker;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QThread>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 设置标签中的文本对齐方式ui->label->setAlignment(Qt::AlignCenter);qDebug()<<"主线程对象地址:"<<QThread::currentThread();//创建线程对象QThread *sub = new QThread;worker = new MyWork;//将创建的工作类对象移动到创建的子线程对象中worker->moveToThread(sub);//启动线程sub->start();//将点击按钮事件与doWork函数绑定。如果用按钮自带的槽函数,不知道怎么回事,子线程和主线程是同一个connect(ui->pushButton,&QPushButton::clicked,worker,&MyWork::doWork);//将用于传递数字的信号curNumber和用于在窗口标签中展示的槽函数showNum绑定connect(worker,&MyWork::curNumber,this,&Widget::showNum);
}Widget::~Widget()
{delete ui;
}// 槽函数,用于接收信号传递的数字,然后在标签中显示数字
void Widget::showNum(int num)
{ui->label->setNum(num);
}//点击鼠标,子线程中的doWork函数开始工作
//void Widget::on_pushButton_clicked()
//{
//    worker->doWork(); //doWork中每数一个数会通过信号curNumber发送给接收者
//}

问题:当使用对按钮右键创建的槽函数执行doWork时,主线程和子线程是同一个。

在这里插入图片描述

数数时,界面依旧卡顿。不知道为什么。

参考链接

Qt中多线程-线程池的使用-C/C++/qt

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

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

相关文章

pands常用操作

1.导入库和文件读取和文件分信息分析 import pandas as pd import numpy as np csvf pd.read_csv(D:/各个站程序版本说明.csv) csvf.info() <class pandas.core.frame.DataFrame> RangeIndex: 51 entries, 0 to 50 Data columns (total 6 columns):# Column Non-Nul…

java面试题整理

2023.2.14&#xff08;第二天&#xff09; 数组是不是对象&#xff1f; 在Java中&#xff0c;数组是对象。数组是一种引用类型&#xff0c;它可以存储固定大小的相同类型的元素序列。在Java中&#xff0c;数组是通过new关键字创建的&#xff0c;它们在内存中被分配为对象&…

「数据结构」MapSet

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;欢迎点赞收藏加关注哦&#xff01; Map&Set &#x1f349;概念&#x1f349;模型&#x1f349;Map&#x1f34c;TreeMap和HashMap的区别&#x1f34c;Map常用方…

2048游戏C++板来啦!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习如何用C编写一个2048小游戏。 文章目录 1.2048的规则 2.步骤实现 2.1: 初始化游戏界面 2.1.1知识点 2.1.2: 创建游戏界面 2.2: 随机…

Days 31 ElfBoard 自启脚本中打开看门狗

1.在开机自启脚本中打开看门狗 rootELF1:~# vi /etc/rc.local 2.在自启脚本中添加上之后&#xff0c;然后在咱们的QT界面中找到看门狗应用&#xff0c; 发现显示打开看门狗失败&#xff1a; 3.修改看门狗源码&#xff0c;设置了超时时间后&#xff0c;关闭/dev/dev/watchdog节…

【Tomcat】:One or more listeners failed to start.报错解决方案

报错信息:One or more listeners failed to start. Full details will be found in the appropriate container log file. 具体就是web.xml此配置报错: 服务器启动错误Tomcat:One or more listeners failed to start.报错解决方案 IDEA:在使用IDEA运行SSM项目的时候 , Tomcat运…

error MSB8008: 指定的平台工具集(v143)未安装或无效。请确保选择受支持的 PlatformToolset 值解决办法

右击解决方案&#xff0c;选择属性 将工具集为143的修改为其他&#xff0c;如图 重新编译即可运行

网络原理(3)--以太网协议,DNS

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网络原理(3)–以太网协议,DNS 在网络原理(2)中介绍了网络层中的一个重要的协议–ip协议,网络层关注的通信时的起点和终点,而数据链路层更加"底层"一些,关注的是传输过程…

【Effective Objective - C 2.0】——读书笔记(四)

文章目录 二十三、通过委托与数据源协议进行对象间通信二十四、将类的实现代码分散到便于管理的数个分类之中二十五、总是为第三方的分类名称加前缀二十六、切勿在分类里面声明属性二十七、使用“class-continuation分类”隐藏实现细节二十八、通过协议提供匿名对象 二十三、通…

springboot187社区养老服务平台的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

MySQL 基础知识(六)之数据查询(一)

目录 1 基本查询 1.1 查询相关列 (select * / 列名) 1.2 别名 (as) 1.3 去重 (distinct) 1.4 对列中的数据进行运算 (、-、*、/) 2 条件查询 (where) 2.1 等值查询 () 2.2 非等值查询 (>、<、>、<、!、><) 2.3 逻辑判断 (and、or、not) 2.4 区间判…

源码推荐:hello-algo @ github

github https://github.com/krahets/hello-algo 本项目旨在创建一本开源、免费、对新手友好的数据结构与算法入门教程。全书采用动画图解&#xff0c;结构化地讲解数据结构与算法知识&#xff0c;内容清晰易懂&#xff0c;学习曲线平滑。算法源代码皆可一键运行&#xff0c;支…

上位机图像处理和嵌入式模块部署(借鉴与学习)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于很多学院派的同学来说&#xff0c;他们对市场的感觉一般是比较弱的。如果写一个软件的话&#xff0c;或者说开发一个项目的话&#xff0c;他们…

(一)【Jmeter】JDK及Jmeter的安装部署及简单配置

JDK的安装和环境变量配置 对于Linux、Mac和Windows系统&#xff0c;JDK的安装和环境变量配置方法略有不同。以下是针对这三种系统的详细步骤&#xff1a; 对于Linux系统&#xff1a; 下载适合Linux系统的JDK安装包&#xff0c;可以选择32位或64位的版本。 将JDK的安装包放置…

VueCLI核心知识3:全局事件总线、消息订阅与发布

这两种方式都可以实现任意两个组件之间的通信 1 全局事件总线 1.安装全局事件总线 import Vue from vue import App from ./App.vueVue.config.productionTip false/* 1.第一种写法 */ // const Demo Vue.extend({}) // const d new Demo()// Vue.prototype.x d // 把Dem…

RK3568平台开发系列讲解(实验篇)用户空间和内核空间数据交换

🚀返回专栏总目录 文章目录 一、用户空间和内核空间数据交换二、实验驱动代码三、应用测试代码沉淀、分享、成长,让自己和他人都能有所收获!😄 一、用户空间和内核空间数据交换 内核空间和用户空间的内存是不能互相访问的。但是很多应用程序都需要和内核进行数据的交换,…

【AI视野·今日NLP 自然语言处理论文速览 第七十八期】Wed, 17 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 17 Jan 2024 (showing first 100 of 163 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deductive Closure Training of Language Models for Coherence, Accur…

优化策略模式,提高账薄显示的灵活性和扩展性

接着上一篇文章&#xff0c;账薄显示出来之后&#xff0c;为了提高软件的可扩展性和灵活性&#xff0c;我们应用策略设计模式。这不仅仅是为了提高代码的维护性&#xff0c;而是因为明细分类账账薄显示的后面有金额分析这个功能&#xff0c;从数据库后台分析及结合Java语言特性…

2024幻兽帕鲁服务器创建教程_阿里PK腾讯超简单

幻兽帕鲁官方服务器不稳定&#xff1f;自己搭建幻兽帕鲁服务器&#xff0c;低延迟、稳定不卡&#xff0c;目前阿里云和腾讯云均推出幻兽帕鲁专用服务器&#xff0c;腾讯云直接提供幻兽帕鲁镜像系统&#xff0c;阿里云通过计算巢服务&#xff0c;均可以一键部署&#xff0c;鼠标…

vscode 提取扩展时出错。XHR failed

检查 vscode 设置中的代理服务器&#xff0c;位置如下图 清空 vocode 中的 Proxy&#xff0c;我黄线框的部分&#xff0c;内容清空。 检查电脑系统环境变量&#xff0c;是否设置了 http_proxy 和 https_proxy&#xff0c;如果有设置&#xff0c;则删除这两项&#xff0c;下载完…