先了解GCD 同步异步
-
dispatch_async
异步执行任务的函数。- 不用等待当前语句执行完毕,就可以执行下一条语句。
- 会开启线程执行
block
的任务。 - 异步是多线程的代名词。
-
dispatch_sync
同步函数。- 必须等待当前语句执行完毕,才会执行下一条语句。
- 不会开启线程。
- 在当前执行
block
任务。
-
block
块是在函数内部执行的。
正常代码如下
先创建一个并发队列 加到异步函数中,里面有三个任务。分别是
NSLog(@"2");``Block块
NSLog(@"4");
代码:
dispatch_queue_t queue = dispatch_queue_create("bobo", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
结果如下 结果是 1 5 2 3 4
结果分析:
代码从上向下执行,先输出
1
,因为是异步函数
,不会出现线程等待
(护犊子
)所以会继续输出5
,然后执行异步函数
内执行任务 先输出2
,然后遇到同步函数
(必须等待当前语句执行完毕,才会执行下一条语句
),所以先执行完
Block代码块才能执行4 所以先输出
3在输出
4`
GCD死锁代码
将上面的代码并发改成串行 代码如下:
// 并发队列 DISPATCH_QUEUE_CONCURRENT
// 串行队列 DISPATCH_QUEUE_SERIAL 死锁
dispatch_queue_t queue = dispatch_queue_create("bobo", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
结果如下 结果是 1 5 2 死锁
结果分析:
先执行任务
1
,串行队列,再执行异步函数
,异步函数
不用的等待,执行5
任务,再执行异步函数
,因为是串行(FIFO)
,先进先出
原则,先执行2
任务,再执行block
块任务,再执行4
任务,因为block
块是同步函数(必须等待当前语句执行完毕,才会执行下一条语句
),所以先执行block块,block块又添加了3
任务到队列后面,串行队列任务现在是任务2
,任务block
,任务4
,任务3
,又因为4
任务在3
任务前面,所以3
要等4
任务结束,4
要等block
块结束block
要等3
任务结束 才走4
,所以就出现了死锁
(dispatch_sync_slow
)的现象