【iOS】多线程基础

news2025/2/8 7:59:34

【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.coloradmin.cn/o/2251494.html

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

相关文章

ArraList和LinkedList区别

文章目录 一、结构不同二、访问速度三、插入和删除操作的不同1、决定效率有两个因素:数据量和位置。2、普遍说法是“LinkedList添加删除快”,这里是有前提条件的 四、内存占用情况五、使用场景六、总结 一、结构不同 LinkedList:它基于双向链…

芯片测试-RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度等

RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度 💢S参数💢💢S11与return loss,VSWR,反射系数💢💢S21,插入损耗和增益&#…

arkTS:持久化储存UI状态的基本用法(PersistentStorage)

arkUI:持久化储存UI状态的基本用法(PersistentStorage) 1 主要内容说明2 例子2.1 持久化储存UI状态的基本用法(PersistentStorage)2.1.1 源码1的相关说明2.1.1.1 数据存储2.1.1.2 数据读取2.1.1.3 动态更新2.1.1.4 显示…

《Django 5 By Example》阅读笔记:p455-p492

《Django 5 By Example》学习第 16 天,p455-p492 总结,总计 38 页。 一、技术总结 1.myshop (1)打折功能 使用折扣码实现,但是折扣码是手动生成的,感觉实际业务中应该不是这样的。 (2)推荐功能 使用 Redis 做缓存&#xff0…

深入浅出:开发者如何快速上手Web3生态系统

Web3作为互联网的未来发展方向,正在逐步改变传统互联网架构,推动去中心化技术的发展。对于开发者而言,Web3代表着一个充满机遇与挑战的新领域,学习和掌握Web3的基本技术和工具,将为未来的项目开发提供强大的支持。那么…

otter 高可用策略

关于otter高可用在设计之初,提供了这样几个基本的需求: 1.网络不可靠,异地机房尤为明显. 2.manager/node的jvm不可靠,需要考虑异常crash情况 3.node的jvm不可靠,需要考虑异常crash的情况 4.数据库不可靠,需…

C底层 函数栈帧

文章目录 一,什么是寄存器 二,栈和帧 前言 我们在学习c语言程序的时候,是不是有很多的疑问,如 1,为什么形参不可以改变实参 2,为什么我们编写程序的时候会出现烫烫烫......这个乱码 3,那些局…

力扣1382:将二叉搜索树便平衡

给你一棵二叉搜索树,请你返回一棵 平衡后 的二叉搜索树,新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法,请你返回任意一种。 如果一棵二叉搜索树中,每个节点的两棵子树高度差不超过 1 ,我们就称这棵二…

亚马逊自研大语言模型 Olympus 即将亮相,或将在 LLM 竞赛中掀起新波澜

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

指针与引用错题汇总

int *p[3]; // 定义一个包含 3 个指向 int 的指针的数组int a 10, b 20, c 30; p[0] &a; // p[0] 指向 a p[1] &b; // p[1] 指向 b p[2] &c; // p[2] 指向 c // 访问指针所指向的值 printf("%d %d %d\n", *p[0], *p[1], *p[2]); // 输出: 10 20 30…

vscode ctrl+/注释不了css

方式一.全部禁用插件排查问题. 方式二.打开首选项的json文件,注释掉setting.json,排查是哪一行配置有问题. 我的最终问题:需要将 "*.vue": "vue",改成"*.vue": "html", "files.associations": { // "*.vue": &qu…

医疗知识图谱的问答系统详解

一、项目介绍 该项目的数据来自垂直类医疗网站寻医问药,使用爬虫脚本data_spider.py,以结构化数据为主,构建了以疾病为中心的医疗知识图谱,实体规模4.4万,实体关系规模30万。schema的设计根据所采集的结构化数据生成&…

上传镜像docker hub登不上和docker desktop的etx4.vhdx占用空间很大等解决办法

平时使用docker一般都在Linux服务器上,但这次需要将镜像上传到docker hub上,但是服务器上一直无法登录本人的账号,(这里的问题应该docker 网络配置中没有开代理的问题,因服务器上有其他用户使用,不可能直接…

大型复杂项目管理怎么结合传统与敏捷

大型复杂项目管理需要综合运用传统的瀑布模型与敏捷方法,两者各具优势,可以在不同的项目阶段和需求下发挥最大效能。首先,在项目的初期阶段,传统方法的详细规划和需求分析能够帮助确保项目方向正确、资源充足;敏捷方法…

PVE中VLAN的设置要点

使用这个拓扑进行连接无法直接访问PVE PVE 设置如下: 核心重点:PVE 的 vmbr0 接口直接绑定了 enp2s0,这会导致 VLAN 流量无法正确处理,因为 PVE 没有专门为 VLAN 3 配置接口。 1.vmbr0 和 vmbr0.3 都是绑定在物理接口 enp2s0 上&…

网络安全防范技术

1 实践内容 1.1 安全防范 为了保障"信息安全金三角"的CIA属性、即机密性、完整性、可用性,信息安全领域提出了一系列安全模型。其中动态可适应网络安全模型基于闭环控制理论,典型的有PDR和P^2DR模型。 1.1.1 PDR模型 信息系统的防御机制能抵抗…

.net —— Razor

文章目录 项目地址一、创建一个Razor项目1.1 创建项目1.2 创建项目所需文件夹1.3 配置项目二、创建Category页面2.1 创建Category的展示页面2.2 增删改2.2.1 创建Edit的razor视图项目地址 教程作者:教程地址:代码仓库地址:所用到的框架和插件:dbt airflow一、创建一个Razo…

学习视频超分辨率扩散模型中的空间适应和时间相干性(原文翻译)

文章目录 摘要1. Introduction2. Related Work3. Our Approach3.1. Video Upscaler3.2. Spatial Feature Adaptation Module3.3. Temporal Feature Alignment Module3.4. Video Refiner3.5. Training Strategy 4. Experiments4.1. Experimental Settings4.2. Comparisons with …

Netty的心跳机制怎么实现的?

大家好,我是锋哥。今天分享关于【Netty的心跳机制怎么实现的?】面试题。希望对大家有帮助; Netty的心跳机制怎么实现的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Netty 的心跳机制用于维持客户端和服务器之间的…

深度学习:自然语言处理

一、引言 自然语言处理作为人工智能领域的关键分支,致力于使计算机能够理解、分析和生成人类语言。近年来,随着深度学习技术的迅猛发展,自然语言处理取得了前所未有的突破,一系列创新技术和应用不断涌现,极大地推动了…