iOS底层原理(23) - GCD分析上

182 阅读1分钟

GCD概念

image.png

将任务添加到队列,并指定任务执行的函数。

函数

image.png

队列

image.png

串行队列遵循 FIFO 原则

函数与队列

image.png

死锁案例

死锁的时候,会走到 dispatch_sync_f_slow.

dispatch_queue_t queue = dispatch_queue_create("cooci", DISPATCH_QUEUE_SERIAL);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"2");
    dispatch_sync(queue, ^{
        NSLog(@"3");
    });
});
NSLog(@"4");
分析上面的代码
前提知识

同步队列遵循 FIFO 原则,同步函数有护犊子的特点。

同步函数和异步函数的区别:异步函数开启子线程,同步函数不开启子线程。

只要是任务都有耗时。

分析

1、按顺序执行,先打印1

2、dispatch_async创建了异步任务,在后台等待执行,继续往下执行打印4

3、异步任务被调用,先打印2

4、创建一个同步任务3,由于queue是串行队列,任务3需要等待异步任务执行完毕后才能执行,但是异步任务又需要等待任务3执行完毕后才能继续往下执行打印4.

加入队列的顺序:

1、

{
   NSLog(@"2");
   dispatch_sync(queue, ^{
       NSLog(@"3");
   });
}

2、NSLog(@"2");

3、

{
   NSLog(@"3");
}

4、NSLog(@"3");

2任务先执行,3要等待1执行完毕,1要等待4执行完毕,4要等待3执行完毕,相互等待,所以造成了死锁。

GCD面试题解题思路

主要看两方面: 先看队列,再看函数,其次看任务的执行速度

  1. 串行队列,任务有序执行
  2. 并发队列,任务无序执行
  3. 同步函数,会阻塞当前线程
  4. 异步函数,可能会开辟新的线程,不会阻塞当前线程