iOS 客户端-Objective-C 多线程编程与 GCD | 青训营笔记

199 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第21天

前言

今天学习到的是【iOS 客户端专场 学习资料一】第四届字节跳动青训营的第六节:Objective-C 多线程编程与 GCD:Grand Center Dispatch大中心调度,GCD是异步执行任务的技术之一,一般,将应用程序中记述的线程管理用的代码在系统级中实现,开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。

本节课知识点大纲

image.png

多线程基础概念

进程与线程

进程:程序运行的一个实例,是资源分配的最小单位,独立地运行在其专用受保护的内存空间内

线程:一个进程可以包含多个线程,线程是操作系统实施调度的最小单位

每个线程之间共享进程的内存空间(代码段、数据段、堆等)及一些进程级的资源(如打开文件等)

每个线程有寄存器、栈、线程局部存储(TLS)等私有数据

串行、并行、并发

串行:任务有序地一个一个地执行,前一个任务执行完之后才能执行下一个任务

并行:多个任务在同一时刻被执行

并发:多个任务在同一时间段内需要被执行,侧重点是这个现象的“发生”

以核酸检测队伍为例,如何理解这些概念?

多线程编程又称为并发编程,让多个 CPU 并发处理多个线程的指令,从而提高程序的执行效率

线程生命周期和线程调度

线程 的生命周期:包括新建、就绪、运行、阻塞、死亡五种状态

线程 调度:当在单个处理器上运行多个线程,操作系统会让这些线程轮流执行一小段时间,宏观上

“看起来”这些线程是同时执行的。不断地在处理器上切换不同线程的行为称为线程调度

RunLoop 和主线程

RunLoop 是事件接收和分发机制的一个实现,可以让线程在适当的时间处理任务不会退出。iOS App中,主线程的 RunLoop 在程序运行时就会启动,其他线程的 RunLoop 需要手动开启。RunLoop 的基本作用有:保持程序持续运行、处理程序中的各种事件、节省 CPU 资源提高程序性能,在必要的时候线程会被唤醒进行工作,否则会进入休眠,休眠时不占用 CPU。

主线程: iOS App 启动时默认会开启一条线程,称为“主线程”。主线程默认开启 RunLoop,使得主线程可以及时刷新 UI 界面和处理 UI 交互事件(如点击、滑动、拖拽等),所以主线程又称为“UI 线程”。耗时操作会妨碍主线程中的主循环的执行,从而引起 App 卡顿问题。通过多线程编程,将耗时操作放到子线程执行,在必要时再回到主线程做刷新操作,可以使程序运行更加流畅。

多线程编程的优缺点

优点:

  • 能适当地提高程序的执行效率
  • 能适当地提高资源利用率

缺点:

  • 创建线程、线程调度都是有开销成本的,如果开启大量线程,会降低程序的性能
  • 需要谨慎处理线程安全问题,增加了程序设计的复杂度

多线程实现方案与GCD

多线程编程实现方案对比

使用 GCD 实现多 线程 编程的好处:

  • 自动使用更多 CPU 内核
  • 自动管理线程的生命周期
  • 提供了易于使用的并发模型
  • 编码更加简洁,无需多余的线程管理任务

GCD 接口介绍

任务与队列

任务:即在线程中执行的代码,在 GCD API 中以 block 的形式提交到队列

队列:任务派发队列(先进先出FIFO,First-In-First-Out),任务追加到派发队列后按照先进先出的次序派发到对应线程进行处理

串行队列和并发队列

串行 队列:队列中的任务在单个线程中顺序执行,执行中的任务结束后才能继续执行下一个任务

并发 队列:队列中的任务在异步执行的情况下可以分发到多个线程下同时执行

同步执行与异步执行

同步执行(dispatch_sync):

  • 提交任务到指定队列,在该任务执行结束之前会一直等待
  • 提交的任务只能在当前线程执行,不具备开启线程的能力

异步执行(dispatch_async):

  • 提交任务到指定队列,继续往下执行不等待任务执行结束
  • 可以在新的线程中执行任务,具备开启线程的能力

引用参考:

课外补充引用:

文章学习来源:

感谢以上作者的文章,今天的学习收获满满!!Thanks and HappyCoding!