理解GCD
October 29, 2019队列
队列用来调度任务,也可以简单理解为如何提供任务.分为串行和并行队列两种.
- 串行队列是按顺序提供任务的,当前面任务完成后,才提供下一个任务.任务的执行及完成是有先后顺序的.
- 并行队列队列中其实也是按顺序提供任务的,只是下一个任务的提供并不依赖于前一个任务的执行完成,所以看起来提供任务是并行的.
队列本身不会创建线程来执行任务,就是简单的把队列理解为一个存储任务的容器好了.
同步和异步
-
同步
在当前线程(不是新创建的线程)执行队列中的任务,这里无论是串行还是并行队列,
都是任务执行完了才能继续往下走前面的任务执行完毕后面的任务才能继续执行. 同步情况下串行和并行队列行为一至,决定同步行为的是同步操作sync,不是队列的类型. -
异步
新建线程执行队列中的任务. 分两种情况:
串行队列,在一个新建的线程中对串行队列中的任务依次顺序执行(如果有多个任务的话)
并行队列,从队列中
依次
取n个任务,并开启n个线程执行任务.
同异步和队列的关系
-
串行队列可以控制任务执行完成先后顺序,无论这个任务是在当前线程,还是另外一个线程.
-
同步可以
控制
当前线程执行任务的先后顺序,无论这个任务是在串行队列还是并行队列. -
并行队列可以
依次
很快
提供更多任务 -
异步可以根据不同的队列新建线程执行队列中的任务.
同,异步与串行,并行队列的组合可以提供不同的任务执行策略.
- 同步+串行队列
- 同步+并行队列
- 异步+串行队列
- 异步+并行队列
同步+串行队列
这种情况其实用的很少,一般不这么用,如果一定要这么用,一定要避免在当前的任务中又加入新的任务到同一个串行队列,这样就会造成死锁.原因很简单.
同步+并行队列
任务执行顺序效率跟上面一样,但不会有死锁的问题了.
异步+串行队列
新开一个线程,所有的任务在这个新开的线程里串行同步执行
异步+并行队列
这个提供了最大的并行,并且对同步没有什么要求和控制.
简单总结一下: 队列控制任务执行顺序,同异步控制线程执行
死锁
死锁的产生原因很简单,就是你等我,我等你,最后死等,等死.
对于GCD
- 只有同步才有可能产生死锁,异步是不可能产生死锁.
- 只有同步+串行队列,并且在一个任务中向同一个串行队列增加任务时才会产生死锁.
这里的同异步指的是针对当前执行线程而言的.
如果你异步执行一个串行队列任务,其实就是在一个新线程里执行这个队列,在这个线程里,如果你又新建一个同步任务到这个串行队列里,当然会产生死锁.所以说这里的同步异步一定针对当前执行线程而言的.
主队列和主线程
程序都有主线程,对于GUI程序也叫他UI线程.
主线程的代码是放在一个叫做主队列的串行队列中的 (通过dispatch_get_main_queue()
可以获取这个队列).
反过来说,主队列中的任务都是在主线程中执行的.
在主线程中向主队列添加同步任务一定是会死锁的
全局队列
全局队列是个并行队列,通过 dispatch_get_global_queue
获取