swift 中的并发

17 Mar 2025 | 4 分钟阅读

在本教程的前一节中,我们讨论了 Swift 中的 GCD 概念,它允许 Swift 中的多线程。 在本教程的这一部分中,我们将讨论 Swift 中线程的并发执行。 我们还将包括 GCD 使用的队列类型和 QoS 类。

正如我们已经提到的,Grand-Central-Dispatch (GCD) 使用 Dispatch 队列,该队列用于任务提交,其中任务以先进先出的方式执行。 在 iOS 中,进程或应用程序包含一个或多个线程; 操作系统负责独立于彼此地调度和管理线程。

但是,每个线程都可以并发执行。 操作系统决定哪些线程将并发执行,以及何时执行。 存档并发最常用的方法之一是时间片,其中每个线程都被赋予相同的执行时间,并且系统在每个时间间隔执行上下文切换。 时间片主要在单核系统中存档。

另一方面,多核系统可以使用并行性来同时执行多个线程。 但是,GCD 构建在线程之上; 它管理一个共享线程池,我们可以在其中添加代码块到调度队列。 GCD 始终根据系统和可用资源来决定所需的并行量。

调度队列

正如我们已经在上一节中讨论的那样,GCD 在调度队列上运行。 swift 中的调度队列是 DispatchQueue 的一个实例,我们将任务提交到此队列。 GCD 以先进先出的顺序执行调度队列中的任务。 在这里,调度队列是线程安全的,可以由多个线程同时访问。

但是,队列可以是并发的或串行的。 顾名思义,串行队列在给定的时间内仅执行一个线程。 在这里,GCD 决定了执行时序。 我们永远无法知道执行单个任务所花费的时间。

Concurrency in swift

另一方面,并发队列同时执行多个任务。 我们永远无法知道开始下一个任务需要多少时间。 任务将以添加的相同顺序开始执行。 但是,它们可能会以不同的顺序结束。 我们无法假设一次运行的线程数。

Concurrency in swift

这里,这取决于 GCD,何时启动线程。 如果两个线程的执行重叠,GCD 还会决定是否在不同的核心上运行任务。

GCD 有三种类型的队列可用。

  1. 主队列:主队列在主线程上运行,它执行线程的串行执行。
  2. 全局队列:全局队列是一个并发队列,由整个系统共享。 有四个全局队列以不同的优先级运行。 优先级为高、默认、低和后台,其中后台优先级队列具有最低优先级。
  3. 自定义队列:开发人员创建自定义队列。 它们可以是并发的或串行的。

QoS 类

当任务发送到全局队列时,我们指定服务质量类属性。 QoS 类确定任务的优先级,然后允许 GCD 执行它们。

系统中存在以下几类 QoS 类。

  1. 用户交互: 当我们在 iOS 中启动应用程序时,为了获得良好的用户体验,我们需要立即执行一些任务。 这些任务是用户交互式的,用于为用户提供良好的体验。 作为开发人员,我们必须将这些任务用于 UI 更新、事件处理和小工作负载。 用户交互式任务需要在主线程上执行。
  2. 用户发起: 这些任务由用户从用户界面启动。 这些是异步任务,当用户在应用程序中等待立即结果时使用,例如某些 API 调用。 用户发起的任务在优先级高的全局队列中执行。
  3. 实用工具: 这些是长时间运行的任务,通常带有进度指示器。 这些类型的线程用于联网、计算、I/O 等。这些任务在优先级低的全局队列中执行。

后台: 这些是在应用程序后台运行的任务。 用户不知道这些任务。 这些任务用于预取、下载、上传、维护和其他类似任务。 这必须在后台全局优先级队列中执行。


下一个主题处理后台任务