201623314875_.pic.jpg
分析问题前现需要明白原理,了解清楚本质才能分析透彻。
1、首先我们要明白什么是GCD
Grand Central Dispatch (GCD) 是异步执行任务技术之一。会自动的根据CPU的使用情况,创建线程来执行任务,并且自动的运行到多核上,提高程序的运行效率。对于开发者来说,在GCD层面是没有线程的概念的,只有队列(queue),任务都是以block的方式提交到对列上,然后GCD会自动的创建线程池去执行这些任务。
GCD 的核心:队列 、任务 、追加任务的方法
1.1 、DispatchQueue(任务队列)
执行任务的等待队列,按照追加顺序先进先出(FIFO)执行处理。
队列的两种类型:Serial Dispatch Queue 和 Concurrent Dispatch Queue
截屏2021-04-09 下午5.18.13.png
1.2 、任务
使用闭包‘’定义执行的任务‘’
// 创建串行队列
let serialQueue = DispatchQueue.init(label: "com.start")
serialQueue.async {
print("异步追加任务")
}
1.3 、追加任务的方法
通过同步(sync)和异步(async)方法追加任务到队列
- async是将指定的任务非同步的追加到指定的Dispatch Queue,不做任何等待。
- sync是将指定的任务追加到指定的Dispatch Queue,在追加任务执行结束前,一直等待(意味着当前线程停止,等待追加任务执行结束后继续执行)。
2、场景分析
2.1异步追加任务嵌套同步追加任务导致线程锁死
func dispatchSerialQueue1(){
print(Thread.current)
// 创建串行队列
let serialQueue = DispatchQueue.init(label: "com.start")
// 主线程打印: 1
print("1")
// 串行队列异步添加任务 (当前线程继续执行)
serialQueue.async {
print(Thread.current)
// 串行队列创建的线程执行打印: 2
print("2")
// 串行队列同步添加任务 (当前线程暂停 等待添加的任务执行完)
serialQueue.sync {
print("3")
}
print("4")
}
// 主线程打印: 5
print("5")
}
截屏2021-04-09 下午4.16.49.png
分析:
1.主线程内创建串行任务队列
2.串行队列异步添加任务,主线程不需要等待继续执行,系统创建线程执行任务
3.cpu为任务队列创建的子线程(number = 7),执行添加的任务
4.任务内部同步添加新任务,导致当前执行任务的子线(number = 7)程暂停
5.同步添加任务需要等待添加的任务执行结束,而新任务执行线程暂停,导致底层上报错误奔溃。