ios 面试题之多线程死锁

拈花ヽ惹草 提交于 2019-12-01 01:35:12

###### 十、 死锁

 

死锁就是队列引起的循环等待

 

**1、一个比较常见的死锁例子:主队列同步**

 

``` 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    dispatch_sync(dispatch_get_main_queue(), ^{

       

        NSLog(@"deallock");

    });

    // Do any additional setup after loading the view, typically from a nib.

}

```

 

在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。

同步对于任务是立刻执行的,那么当把任务放进主队列时,它就会立马执行,只有执行完这个任务,viewDidLoad才会继续向下执行。

而viewDidLoad和任务都是在主队列上的,由于队列的先进先出原则,任务又需等待viewDidLoad执行完毕后才能继续执行,viewDidLoad和这个任务就形成了相互循环等待,就造成了死锁。

想避免这种死锁,可以将同步改成异步dispatch_async,或者将dispatch_get_main_queue换成其他串行或并行队列,都可以解决。

 

**2、同样,下边的代码也会造成死锁:**

 

``` 

dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

 

dispatch_async(serialQueue, ^{

       

        dispatch_sync(serialQueue, ^{

            

            NSLog(@"deadlock");

        });

    });

```

 

外面的函数无论是同步还是异步都会造成死锁。

这是因为里面的任务和外面的任务都在同一个serialQueue队列内,又是同步,这就和上边主队列同步的例子一样造成了死锁

解决方法也和上边一样,将里面的同步改成异步dispatch_async,或者将serialQueue换成其他串行或并行队列,都可以解决

 

``` 

   dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    

    dispatch_queue_t serialQueue2 = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

    

    dispatch_async(serialQueue, ^{

       

        dispatch_sync(serialQueue2, ^{

            

            NSLog(@"deadlock");

        });

    });

```

 

这样是不会死锁的,并且serialQueue和serialQueue2是在同一个线程中的。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!