lufei's Studio.

iOS 可能有用的多线程小知识

字数统计: 760阅读时长: 2 min
2020/10/29 Share

前言

Grand Central Dispatch (简称 GCD) 是一套苹果提供的用来更方便的操作线程的 api。

基于 Grand Central Dispatch,我们可以了解一下,关于多线程的一些小知识。

一些概念

Queues

中文可以翻译为「队列」,是一种先进先出(FIFO, First-in First-out)的数据结构。

Serial vs Concurrent

这两个是反义词,主要是在描述当每项任务(task)被执行时,跟其他任务的关系。

  • Serial(照顺序执行的)

serial queues 的意思就是指这个队列里的任务是按照顺序执行的,一次执行一个,前一个执行完,才会执行下一个。

  • Concurrent(同时进行的)

也就是说 concurrent queues 代表这个队列里的任务会按照顺序「开始」执行,但是因为是 concurrent,不会等待上一个完了才执行下一个,因此每个任务执行结果的时间是不可预测的。

Synchronous vs Asynchronous

  • Synchronous (同步)

一个 Synchronous 的 function 只有在里面的任务完成后才会回传值,也就是说,只有当前任务完成之后,当前线程才能继续接下来的任务,也就是平时所说的 Synchronous 的 function 会阻塞当前线程。

  • Asynchronous(异步)

相对于 Synchronous,asynchronous 的 function 会立刻回传值,asynchronous function 里的任务会按照顺序执行,但是 function 不会等待其他的任务执行完,它会马上回传值,因此 asynchronous function 不会造成所在的线程阻塞。

一些小知识

任务在普通队列里的时候

  • 只有 Async 才会开启新的线程

  • 在 Concurrent 的 Queue 下,用 Async 执行 Tasks 会开启多条线程

  • 在 Concurrent 的 Queue 下,用 Async 执行 Tasks 是速度最快的方式

任务在主队列的时候

  • 主队列的任务都会在主线程执行,不会开启新的线程

  • 主队列就算 Async,也不会开启新线程,而是会在主线程空闲的时候才会执行异步任务

  • 多个主队列异步的嵌套,会让异步任务在主线程的开始执行时间越来越迟

  • 多个主队列异步的任务,经过测试,它们的执行顺序,也是按照先进先出的原则来处理的

  • 最好不要在主线程异步做耗时任务,比较好的方式是开子线程操作,完成后回到主线程,比如下面这样:

1
2
3
4
5
6
7
8
9
10
11
DispatchQueue.global(qos: .default).async {

/// 一些耗时操作

/// 回到主线程
DispatchQueue.main.async {

/// 主线程操作

}
}

关于 Quality of service (QoS)

QoS (QoSClass) 是一个可以用来定义队列里的任务的执行顺序的 enum,如果没有定义也会有 default 值,当然主队列里的任务的执行优先级最高。

更简单的方式来获取主线程异步和子线程异步的队列

  • 主线程异步的队列
1
2
3
DispatchQueue.main.async {

}
  • 子线程异步的队列
1
2
3
DispatchQueue.global().async {

}

参考

Dispatch

CATALOG
  1. 1. 前言
  2. 2. 一些概念
    1. 2.1. Queues
    2. 2.2. Serial vs Concurrent
    3. 2.3. Synchronous vs Asynchronous
  3. 3. 一些小知识
    1. 3.1. 任务在普通队列里的时候
    2. 3.2. 任务在主队列的时候
    3. 3.3. 关于 Quality of service (QoS)
    4. 3.4. 更简单的方式来获取主线程异步和子线程异步的队列
  4. 4. 参考