一堆概念
广义语境下
单核与多核
硬件概念 最早的双核处理器 Intel 奔腾。
超线程技术:一颗核心以模拟的方式扮作两颗处理器。
进程与线程
对一个操作系统来说,一个程序实例一般是一个进程。进程包括运行中的程序和程序所使用到的内存和系统资源。
线程是程序中的一个执行流,每个线程都有自己的专有寄存器,但代码区是共享的,即不同的线程可以执行同样的函数。
单线程与多线程
单线程是指程序中包含一个执行流。
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
并行与并发
Erlang 之父 Joe Armstrong
单核多线程与多核多线程
单核多线程:并发
多核多线程:线程数小于空余核心数时为并行,大于时为部分并行部分并发
计算密集型任务 与 IO密集型任务
计算密集型任务:特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码、图像渲染等等,全靠CPU的运算能力。
IO密集型任务:涉及到网络、磁盘IO的任务。CPU消耗很少,任务的大部分时间都在等待IO操作完成。
同步和异步
形容具体的一个函数,一段代码。
同步:会逐行执行代码,会对后续代码造成阻塞,直至代码接收到预期的结果之后,才会继续向下执行任务。
异步:调用之后先不管结果,继续向下执行任务。
单线程异步:JavaScript 利用计时器回调,适合 IO 密集型任务。
多线程异步:多核处理,background 线程处理后通知主线程。
串行和并行(iOS语境中)
形容一组操作、函数、一组内多段代码的关系。
串行:“做完一件事,然后再进行下一件事”。
并行:两个异步操作,在不同的线程中同时执行。对于这种拥有多套资源同时执行的方式,我们就将它称为并行 (parallel)。
异步但串行 (通过回调嵌套)
异步且并行
串行 | 并行(多核多线程) | |
---|---|---|
同步 | 可能会造成线程阻塞 | 无 |
异步 | 回调函数 | 并行 |
嵌套起来…异步代码最终都可以被拆解为同步代码和另一段更短的异步代码。
iPhone 均是多核处理器,因此 Swift 中所指的异步大部分情况指的是多线程异步。
iOS 多线程
主线程:UI线程
背景线程:外主线程的其他线程
在主线程(UI线程)进行耗时的操作
利用背景线程进行耗时操作并提供异步回调,避免 卡顿 。
GCD
“DispatchQueue 是一个管理应用程序的主线程或后台线程任务的串行或并发执行的对象。”
—— Apple Developer
指定优先级
- background — 当一个任务对时间不敏感,或者当用户可以在这个过程中做一些其他的互动时,我们可以使用这个方法。比如预先获取一些图片做预加载,或者在后台处理一些数据。这个任务的执行需要一定的时间,几秒或者几分钟,甚至几个小时。
- utility — 长期运行的任务。一些用户可以看到处理过程。例如,下载一些带有指标的地图。这个任务可能需要几秒钟甚至几十分钟的时间。
- userInitiated — 用户从用户界面启动一些任务并等待结果以继续与应用程序交互。这个任务需要几秒钟或一瞬间。
- userInteractive — 用户需要立即完成某些任务,以便能够继续与应用程序进行下一次交互。是一个即时任务。
- 调度组(DispatchGroup)控制并发
- 调度信号量(DispatchSemaphore)控制阻塞
- 调度障碍 Dispatch Barrier 保证线程安全
https://juejin.cn/post/6844903566398717960
GOTO
Go To Statement Considered Harmful
推广结构化并发,解决并发任务生命周期问题
Swift 并发 (协程)
Swift 提供内建的支持,让开发者能以结构化的方式书写异步和并行的代码,… 并发这个术语,指的是异步和并行这一常见组合。
- async/await 实现异步代码的基础
- task 在串行域(主线程)中开启并行域
- actor 保障并发安全
- sendable 线程之间信息传输
最终
- 异步函数可以帮助我们写出简单的异步代码,Swift 并发中很多 API 也都是通过异步函数提供的;
- 通过组织结构化并发,可以保证任务的执行顺序、正确的生命周期和良好的取消操作;
- 利用 actor 和 Sendable 等,编译器能保证数据的安全。
GCD 与 Swift 并发比较
线程切换和线程爆炸
详细介绍见王巍老师《Swift 异步和并发》