先了解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)的现象