GCD死锁

作者: 分流替躺欧阳克 | 来源:发表于2019-06-07 23:56 被阅读0次
同步异步串行并发表格

同步,异步:只是对是否开启新线程有影响

  • 同步dispatch_sync(queue,^{}):在当前线程中执行任务,不具备开启新线程的能力
  • 异步dispatch_asyn(queue,^{}):在新的线程中执行任务,具备开启新线程的能力

并发,串行:任务的执行方式

  • 并发:可以多个任务执行

  • 串行:一个个的执行任务

  • 例1

//死锁1
- (void)task{
    dispatch_queue_t queue = dispatch_get_main_queue();
    NSLog(@"执行任务1");
    dispatch_sync(queue, ^{
        NSLog(@"执行任务2");
    });
    NSLog(@"执行任务3");
}

上面代码,dispatch_sync添加的任务,需要里面执行,又因为主队列也是串行队列,所以添加的任务先进队列先执行。任务2是在task这个函数任务加入住线程队列之后才加入主队列,所以需要先等task任务执行后才能执行任务2,但是task任务又要等任务2与任务3执行完才算执行完task。互相等待,导致两个任务都永远不会执行。所以会造成死锁。

  • 例2
//死锁2
- (void)task {
    dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"执行任务2");
        dispatch_sync(queue, ^{
          NSLog(@"执行任务3");
        });
        NSLog(@"执行任务4");
    });
    NSLog(@"执行任务5");
}

因为在queue里先加入了外层block里的任务,这个任务中又往queue里同步加入了一个任务3,,因为是同步加入,所以任务3和block任务在一个线程里,任务3需要马上执行,但是得因为任务3后于外层block任务,所以需要等外层block任务执行完后,才能执行,任务3在外层block任务里面,任务3不执行,外层block任务就执行不完,相互等待,造成死锁

总结:
现象:使用dispatch_sync()往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
原因:串行队列中上一个任务包含下一个需要马上执行的任务时,上一个任务等待下一个任务执行完才能执行,下一个任务又需要上一个任务执行完,才能执行,互相等待就会造成死锁。

相关文章

网友评论

      本文标题:GCD死锁

      本文链接:https://www.haomeiwen.com/subject/opxbxctx.html