【iOS】多线程基础

【iOS】多线程基础

文章目录

  • 【iOS】多线程基础
    • 前言
    • 进程与线程
      • 进程
        • 进程的状态
        • 进程的一个控制结构
        • 进程的上下文切换
      • 线程
        • 为什么要用线程
        • 什么是线程
        • 线程和进程的关系
        • 线程的上下文切换
      • 线程和进程的优缺点
    • 小结

前言

笔者由于对于GCD不是很了解,导致了项目中网络请求哪部分的一个代码冗长且逻辑混乱,很多时候出现了问题也不知道怎么解决,所以笔者决定学习一下多线程的内容,方便自己之后对于GCD的一些内容的理解。

进程与线程

对于任何一个学习计算机的人而言,对于进程和线程这两个词语一定不陌生,但是要具体说出二者的区别,可能还是会支支吾吾说不出个所以然,这里笔者简单介绍一下有关进程和线程的内容。

进程

我们编写的代码都只是一个存储在计算机硬盘的一个静态文件,通过编译后会变成一个二进制可执行文件,当我们运行这个可执行文件后,他会进入内存中,然后我们计算机的cpu会开始执行这个程序的每一条指令,这时候这个运行中的程序就被称作进程, 也就是这个运行的程序实例被叫做进程。

用官方一点的话来讲就是:进程(Process)是计算机中具有一定独立功能的程序关于某个数据集合的一次运行活动。 它可以申请和拥有系统资源,是系统进行资源分配和调度的基本单位(有了多道程序的概念,操作系统就可以对每个程序进行资源的分配)。

这时候,我们的计算机如果执行一个读取硬盘文件的数据内容被执行了,当运行执行读取文件的指令的时候,cpu开始从硬盘读取数据,这里我们不难发现一个问题,我们计算机读取硬盘的顺序是非常缓慢的,如果我们一直让计算机等待这个文件执行完然后在执行下面的内容的话,我们会浪费很多时间,cpu的利用率是非常的低下的。

举个例子,就好比我们吃饭的时候我们一直等待厨师把饭做好,在这期间我们什么事情也不做,就单纯的等待吃饭,这时候我们一般会去抽时间做不同的事情,然后等厨师做好饭就回来吃。所以现在的计算机也采用了这种思想,如果在执行一个进程中读取文件的内容的时候,cpu会切换到另一个进程中去执行另一个进程的相关内容,当硬盘的数据返回的时候,cpu会收到一个中断,cpu在回来执行这个进程的内容。

image-20241130155344174

这种 多个程序,交替执行的思想,就是cpu管理多个进程的初步想法。虽然一个单核的cpu在某一刻只能执行一个进程,但是在一个时间段内却可以执行多个进程,这样就会给我们产生一种并行的错觉,好像这几个进程是一起执行的,但是实际上这种方式叫做并发

image-20241130155734013

现在的主流操作系统都是支持”多任务“的操作系统。

举个例子:也就是操作系统可以同时运行多个任务。比如,你可以一边用浏览器上网,一边听音乐,一边写代码,对于操作系统而言,这就是多任务。

这种并发的效果是通过什么实现的呢?这里笔者引用一段博客:

答案就是时间片轮转调度:简单地说就是把一个处理器划分为若干个短的时间片,每个进程会被操作系统分配一个时间片(即每次被 CPU 选中来执行当前进程所用的时间),每个时间片依次轮流地执行处理各个应用程序,时间一到,无论进程是否运行结束,操作系统都会强制将 CPU 这个资源转到另一个进程去执行,由于一个时间片很短,相对于一个应用程序来说,就好像是处理器在为自己单独服务一样,从而达到多个应用程序在同时进行的效果。通俗的说就是讲时间分为一个个极短的时间段,在相应的时间短中执行相应的程序,因为时间段的时间极短,在我们和程序看来就好像是CPU同时处理多个进程一样。
【iOS】—— 多线程编程八重曲之(一)- 多线程基础

image-20241130161029555

正如同上图每一个方块都是一个时间片,我们的计算机会给这三个程序分配对应的时间片,先运行一个程序,在这个时间片用完之后迅速切换到另一个进程中,再次执行对应的一个时间片,就这样循环往复从而实现了一个并发的效果(原因是时间片非常的短暂,人察觉不出来他的区别)。

进程的状态

在上面的多进程的例子中,我们发现进程大致有着 运行—暂停—运行的一个活动规律,就一般情况来说,一个进程不是自始自终连续不停的运行的,他与并发执行中的其他进程的执行是互相制约的。

所以一个进程在活动期间主要具备了三个基本状态: 运行状态就绪状态阻塞状态

image-20241130161959611

  • 运行:进程占用cpu
  • 就绪:可运行,但是因为某些原因停止运行
  • 阻塞:该进程正在等待某一事件的发生而停止运行

自然还会有另外两个状态,创建和结束的状态

image-20241130162250966

这里笔者直接引用一段别的大佬对于这个状态变迁的描述

image-20241130162649146

图片来自:进程管理

其实进程还有被挂起的一个状态,笔者这里还不是很能理解相关内容,这里涉及到了一个虚拟内存的内容,笔者会在之后了解相关内容。

进程的一个控制结构

在操作系统中是采用 **程序控制块(PCB)**这个数据结构来描述进程的。PCB是一个进程存在的唯一标识,这里笔者可以结合mac的一个活动监视器来解释相关内容。

image-20241130163913407

他包含以下内容:

进程描述内容

  • 进程标识符,也就是上图中的PID
  • 用户标识符,就是上图中用户对应的内容。

进程控制和管理信息

  • 进程的一个状态,如new,ready
  • 进程优先级,进程抢占cpu的优先级

资源分配清单

  • 有关内存地址空间的信息

cpu相关信息

  • CPU各种寄存器的值,以便进程被重新执行后,都能从断点处继续执行。

通过PCB我们就可以实现一个多进程的一个并发。而PCB与PCB之间是用链表来组织的,将就绪状态的进程链接在一起,就是就绪队列。将等待状态的进程链接在一起叫做阻塞队列。

进程的上下文切换

前面我们提到进程间的切换,这个从一个进程切换到另一个进程中运行,被称为上下文切换。

我们也提到了现在的操作系统都是多任务的,所以在每个任务运行钱需要知道任务从哪里进行一个加载,从哪里开始运行。

这个时候,我们就啊哟先帮cpu设置好寄存器和程序计数器。

前者是一块运行速度极快的内存,后者是一个cpu将要执行指令的位置,或者即将执行的下一条指令的位置。这两个部分是CPU执行任何任务前,必须依赖的环境,这个环境就叫做CPU上下文

所以CPU上下文切换接可以理解为:

CPU 上下文切换就是先把前一个任务的CPU上下文(CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。

cpu的上下文切换分成:进程上下文, 线程上下文, 中断上下文

进程的上下文主要包含了:虚拟内存, 栈, 全句变量等用户需要的资源,还包含了寄存器和内核堆栈的等内核空间的资源。

image-20241130171218628

线程

为什么要用线程

这里笔者直接引用一段话:

在早期的操作系统中并没有线程的概念,进程是拥有资源和独立运行的最小单位。任务调度采用的是时间片轮转抢占式调度方式,而进程作为任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。

后来,随着计算机技术的发展,可运行的进程越来越多。进程出现了很多弊端,一是由于进程是资源拥有者,创建、撤消与切换存在较大的时空开销,因此需要引入轻型进程;二是由于对称多处理机(SMP)的出现,可以满足多个运行单位,而多个进程并行开销过大。因此出现了能独立运行的基本单位 —— 线程(Threads)。【iOS】—— 多线程编程八重曲之(一)- 多线程基础

其实线程的出现,主要还是为了减少上下文切换的时候浪费的系统开销,线程之间可以并发运行且共享相同的地址空间,从而减小了进程上下文切换的开销,让程序运行更加流畅。

什么是线程

线程是程序执行中一个单一顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。

同一进程中内多个线程可以共享代码段,数据段,打开的文件等资源。但是每个线程由自己独立的寄存器和栈,可以保证线程的控制流是独立的

image-20241130172134476

优点

  • 一个进程中可以有多个线程
  • 各个线程中可以并发的执行
  • 各个线程之间可以共享地址内存和文件等资源

缺点

  • 某一进程中的一个线程崩溃可能导致该进程内其他线程的的崩溃。
线程和进程的关系
  • 线程是依附于进程的,不能独立存在,它包含在进程之中,是进程中的实际运作单位。进程一旦结束,所有线程都结束。
  • 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
  • 线程是进程中的一个执行单元,由CPU独立调度执行,负责当前进程中任务的执行。一个进程可以有一个或多个线程,线程会拥有自己的堆栈和局部变量(不共享),但是它与同一进程中的多个线程将共享程序的内存空间,也就是该进程中的代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)等系统资源。
线程的上下文切换

线程和进程最大的区别在于:线程是调度的基本单位,而进程则是资源拥有的基本单位

  • 在一个进程中如果只有一个线程,那么可以吧这个进程当作一个线程
  • 当进程拥有多个线程是,这些线程会共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换的时候是不需要修改的。

那我们线程的上下文切换是需要保存那些内容呢?

  1. 如果在同一进程下

    那么切换的时候,只用切换线程的私有数据,比方说寄存器等不共享的数据

  2. 如果不在同一进程下

    那么他的上下文切换和进程上下文一样

所以线程的上下文切换相比进程,开销要小很多,所以我们有了多线程的优点

线程和进程的优缺点

多任务既可以由多进程实现,也可以由单进程内的多线程实现,还可以混合多进程+多线程。混合多进程和多线程的程序涉及到同步、数据共享的问题,这种模型更复杂,实际很少采用。
和多进程相比,多线程的优势在于:

  • 线程的调度与切换比进程快很多,同时创建一个线程的开销也比进程要小很多;
    线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,线程间通信就是读写同一个变量,速度很快。而进程之间的通信需要以通信的方式(Inter Process Communication,IPC)进行。

而多进程的优点在于:

  • 多进程程序更健壮,在多进程的情况下,一个进程崩溃不会影响其他进程,而在多线程的情况下,任何一个线程崩溃会直接导致整个进程崩溃。

小结

笔者这篇文章简单介绍了有关线程和进程的内容,笔者才疏学浅,如有纰漏还请不吝指出。以及笔者对于调度的内容还没有进行一个学习,之后学习会补充上去,接下来才可以方便我们理解iOS中GCD各个函数的一个意义。
参考博客:
【iOS】—— 多线程编程八重曲之(一)- 多线程基础
进程管理

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

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

相关文章

Android矩阵Matrix在1张宽平大Bitmap批量绘制N个小Bitmap,Kotlin(1)

Android矩阵Matrix在1张宽平大Bitmap批量绘制N个小Bitmap,Kotlin(1) import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color import android.graphics.Matri…

vue2+svg+elementui实现花瓣图自定义el-select回显色卡图片

项目需要实现花瓣图,但是改图表在echarts,highCharts等案例中均未出现,有类似的韦恩图,但是和需求有所差距; 为实现该效果,静态图表上采取svg来手动绘制花瓣: 确定中心点,以该点为中…

二百七十八、ClickHouse——将本月第一天所在的那一周视为第一周,无论它是从周几开始的,查询某个日期是本月第几周

一、目的 ClickHouse指标表中有个字段week_of_month,含义是这条数据属于本月第几周。 而且将本月第一天所在的那一周视为第一周,无论它是从周几开始的。比如2024-12-01是周日,即12月第一周。而2024-12-02是周一,即12月第二周 二…

快充协议IC支持全协议,内部集成LDO支持输出电压3.3V,支持宽电压范围3.3~30V

随着快充技术的不断发展,越来越多的电子产品都使用上了快充,市面上大多数受电端取电芯片只有取电功能,而有些产品则需要更多功能支持,例如产品需要快充支持又要读取电压,就只能在使用取电协议芯片的同时再增加一颗串口…

深入傅里叶级数与傅里叶变换:从基础到应用

傅里叶分析是数学、物理和工程领域的一项基础工具,其核心思想是将复杂的信号或函数分解为一系列简单的正弦和余弦函数的叠加。本文将带你从傅里叶级数入门,逐步深入傅里叶变换的概念及其应用场景。 一、傅里叶级数:周期信号的分解 1. 什么是傅…

brew安装mongodb和php-mongodb扩展新手教程

1、首先保证macos下成功安装了Homebrew, 在终端输入如下命令: brew search mongodb 搜索是不是有mongodb资源, 演示效果如下: 2、下面来介绍Brew 安装 MongoDB,代码如下: brew tap mongodb/brew brew in…

记录一次网关异常

记一次网关异常 网关时不时就会出现下面的异常。关键是不知道什么时候就会报错,并且有时候就算什么都不操作,也会导致这个异常。 ERROR org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in schedul…

使用Python和OpenCV自动检测并去除图像中的字幕

在图像处理和视频编辑领域,手动划分区域以定位和处理特定元素(如字幕)是一项耗时且劳动密集型的工作。专业人士常常需要花费大量时间来确保每一帧中的字幕都被精确地定位和移除,这不仅效率低下,而且容易出错。本文介绍…

Algorithm:河内之塔

1. 说明 河内之塔(Towers of Hanoi)是法国人 M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas 曾提及这个故事,据…

A109 PHP+MYSQL+LW+网上论坛网站 军事BBS系统的设计与实现 源码+文档 全套 教程

网上军事论坛网站系统 1.项目摘要2. 研究背景3.项目功能4.界面展示5.源码获取 1.项目摘要 随着计算机网络的普及,如今越来越多的论坛类网站也是数不胜数,各种类型的论坛交流网站,深受当前网友们的喜欢。网上军事论坛网站的成立,是…

【Nacos01】消息队列与微服务之Nacos 介绍和架构

Nacos Nacos 介绍和架构 什么是Nacos https://nacos.io/ https://github.com/alibaba/nacos Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称 是阿里巴巴开源的一个基于JAVA语言的更易于构建云原生应用的动态服务发现、配置管理和服务管理平台…

FolderMove 3.0 |文件夹安全转移,释放C盘空间

FolderMove v3.0是一款可以一键移动文件到其他磁盘的小工具。原版是全英文软件,但提供了汉化无限制版。软件体积小巧,只有约200KB,使用非常简单,无需安装,绿色环保。运行时选择需要移动的文件夹目录即可。FolderMove会…

TypeScript和JavaScript的区别

总结: TypeScript 是 JavaScript 的超集,它在 JavaScript 的基础上添加了强类型、接口、类、泛型等特性,并提供了静态类型检查等工具,让开发者能够在编写代码时更加安全、高效、可靠。与 JavaScript 相比,TypeScript …

学习threejs,使用VideoTexture实现视频Video更新纹理

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️VideoTexture 视频纹理 二、…

【PyTorch】回归问题代码实战

梯度下降法是优化算法中一种常用的技术,用于通过最小化损失函数来求解模型的最优参数。在线性回归中,目标是通过拟合数据来找到一条最适合的直线。梯度下降法通过迭代地调整模型参数,使得损失函数(通常是均方误差)最小…

Springboot入门教程系列HelloWorld

接下来学习Springboot相关的知识,从简单的入门到高级篇【也就是Springboot企业级快速开发的整合部分】,接下来的教程适合入门小白看,简单的说下入门级教程的环境准备 环境准备 jdk 1.8Maven:3.6.1springboot: 2.2.7 目前springboot最新版本为…

koa中间件

文章目录 1. koa中间件简介2. 中间件类型1. 应用级中间件2. 路由级中间件3. 错误处理中间件4. 第三方中间件 3.中间件执行流程 1. koa中间件简介 在Koa中,中间件呈现为一个异步函数,该函数支持 async/await 语法,它接收两个参数:…

【第 1 章 初识 C 语言】1.8 使用 C 语言的 7 个步骤

目录 1.8 使用 C 语言的 7 个步骤 1.8.1 第 1 步:定义程序的目标 1.8.2 第 2 步:设计程序 1.8.3 第 3 步:编写代码 1.8.4 第 4 步:编译 1.8.5 第 5 步:运行程序 1.8.6 第 6 步:测试和调试程序 1.8.…

React 路由与组件通信:如何实现路由参数、查询参数、state和上下文的使用

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

SpringMVC:参数传递之日期类型参数传递

环境准备和参数传递请见:SpringMVC参数传递环境准备 日期类型比较特殊,因为对于日期的格式有N多中输入方式,比如: 2088-08-182088/08/1808/18/2088… 针对这么多日期格式,SpringMVC该如何接收,它能很好的处理日期类…