详解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;它们在内存中被分配为对象&…

Java 中 Hashtable和ConcurrentHashMap的区别

Hashtable和ConcurrentHashMap的区别 Hashtable 和 ConcurrentHashMap 都是 Java 中的集合框架中的 Map 接口实现类&#xff0c;但它们之间有很大的不同&#xff0c;特别是在多线程环境中。下面是它们之间的一些主要区别&#xff1a; 线程安全性&#xff1a; Hashtable 是线程…

<网络安全>《30 网络信息安全基础(1)常用术语整理》

1 肉鸡 所谓“肉鸡”是一种很形象的比喻&#xff0c;比喻那些可以随意被我们控制的电脑&#xff0c;对方可以是WINDOWS系统&#xff0c;也可以是UNIX/LINUX系统&#xff0c;可以是普通的个人电脑&#xff0c;也可以是大型的服务器&#xff0c;我们可以象操作自己的电脑那样来操…

网络世界的基石:深入探索OSI 7层模型的奥秘

引言 在当今互联网和计算机网络的复杂体系中&#xff0c;OSI&#xff08;开放系统互连&#xff09;参考模型提供了一个理解和设计网络通信协议的框架。自1984年由国际标准化组织&#xff08;ISO&#xff09;提出以来&#xff0c;OSI 7层模型已成为网络通信中最基本的概念之一。…

re:从0开始的CSS之旅 15. 浮动

1. 浮动 浮动&#xff1a;使元素浮起来&#xff0c;脱离文档流&#xff0c;从而使盒子能够灵活的移动。 浮动的属性&#xff1a; float 属性设置元素的浮动 可选值&#xff1a; none 元素不浮动&#xff0c;默认在文档流中排列&#xff08;默认值&#xff09; left 元素向左移…

「数据结构」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: 随机…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-ARM按键1*3矩阵键盘编程 (物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd1688 提取码&#xff1a;1688 1、键盘1*3的中断程序 //************************************************ #include "2440addr.h" #include "2440lib.h" #include &…

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运…

.NET Core性能优化技巧

.NET Core作为一个跨平台的开源框架&#xff0c;以其高效、灵活和可扩展的特性受到了广大开发者的青睐。但在实际开发中&#xff0c;如何确保应用程序的性能始终是一个关键的问题。本文将介绍十大.NET Core性能优化技巧&#xff0c;帮助开发者提升应用程序的性能。 1. 使用异步…

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

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

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

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

关于TypeError:无法读取null属性(读取‘isCE‘) -自定义组件库

关于TypeError:无法读取null属性(读取’isCE’) -自定义组件库 大家先看一下这个文章 https://cloud.tencent.com/developer/ask/sof/106913760 这个文章里面给了vite解决方案 这里我给出一个webpack解决方案 首先我建议你的组件库和你的项目进行vue版本锁定 第二补在你的vue.c…

假期作业 11

整理chmod、chgrp、chown指令的应用成文档 chmod 文件分类: bcd-lsp d 目录 - 普通文件 b 块设备驱动文件 磁盘 c 字符设备驱动文件 键盘 鼠标 l link 链接文件 软连接 硬连接 网络编程 s socket 套接字文件 网络编程 p pipe 管道文件 权限内容 r read w write - 无…

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

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

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

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

剑指大数据-企业级数据仓库项目实战

第1章 大数据与数据仓库概论 大数据生态圈分为7层&#xff0c;这7层可以概括为数据采集层、数据计算层、数据应用层3层结构。 第4章 用户行为数据采集模块 4.1日志生成 4.1.1数据埋点 用户行为日志的内容&#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 区间判…