理解GCD

October 29, 2019

队列

队列用来调度任务,也可以简单理解为如何提供任务.分为串行和并行队列两种.

  1. 串行队列是按顺序提供任务的,当前面任务完成后,才提供下一个任务.任务的执行及完成是有先后顺序的.
  2. 并行队列队列中其实也是按顺序提供任务的,只是下一个任务的提供并不依赖于前一个任务的执行完成,所以看起来提供任务是并行的.

队列本身不会创建线程来执行任务,就是简单的把队列理解为一个存储任务的容器好了.

同步和异步

  • 同步

    当前线程(不是新创建的线程)执行队列中的任务,这里无论是串行还是并行队列,都是任务执行完了才能继续往下走 前面的任务执行完毕后面的任务才能继续执行. 同步情况下串行和并行队列行为一至,决定同步行为的是同步操作sync,不是队列的类型.

  • 异步

    新建线程执行队列中的任务. 分两种情况:

    串行队列,在一个新建的线程中对串行队列中的任务依次顺序执行(如果有多个任务的话)

    并行队列,从队列中依次取n个任务,并开启n个线程执行任务.

同异步和队列的关系

  • 串行队列可以控制任务执行完成先后顺序,无论这个任务是在当前线程,还是另外一个线程.

  • 同步可以控制当前线程执行任务的先后顺序,无论这个任务是在串行队列还是并行队列.

  • 并行队列可以依次 很快 提供更多任务

  • 异步可以根据不同的队列新建线程执行队列中的任务.

同,异步与串行,并行队列的组合可以提供不同的任务执行策略.

  1. 同步+串行队列
  2. 同步+并行队列
  3. 异步+串行队列
  4. 异步+并行队列

同步+串行队列

这种情况其实用的很少,一般不这么用,如果一定要这么用,一定要避免在当前的任务中又加入新的任务到同一个串行队列,这样就会造成死锁.原因很简单.

screenshot_20191022_141523 20

同步+并行队列

任务执行顺序效率跟上面一样,但不会有死锁的问题了.

异步+串行队列

新开一个线程,所有的任务在这个新开的线程里串行同步执行

异步+并行队列

这个提供了最大的并行,并且对同步没有什么要求和控制.

简单总结一下: 队列控制任务执行顺序,同异步控制线程执行

死锁

死锁的产生原因很简单,就是你等我,我等你,最后死等,等死.

对于GCD

  1. 只有同步才有可能产生死锁,异步是不可能产生死锁.
  2. 只有同步+串行队列,并且在一个任务中向同一个串行队列增加任务时才会产生死锁.

这里的同异步指的是针对当前执行线程而言的.

如果你异步执行一个串行队列任务,其实就是在一个新线程里执行这个队列,在这个线程里,如果你又新建一个同步任务到这个串行队列里,当然会产生死锁.所以说这里的同步异步一定针对当前执行线程而言的.

主队列和主线程

程序都有主线程,对于GUI程序也叫他UI线程.

主线程的代码是放在一个叫做主队列的串行队列中的 (通过dispatch_get_main_queue() 可以获取这个队列).

反过来说,主队列中的任务都是在主线程中执行的.

在主线程中向主队列添加同步任务一定是会死锁的

全局队列

全局队列是个并行队列,通过 dispatch_get_global_queue 获取