iOS中的线程死锁

作者: ChinaChong | 来源:发表于2018-09-12 18:06 被阅读36次

    线程死锁产生的原因:在一个串行队列的任务中,再向这个队列添加同步任务。


    典型例子:

    image.png

    我们分析一下:


    image.png

    主队列main_queue是一个串行队列,串行队列的特点就是队列中所有任务必须顺序执行。也就是说必须按照添加到队列中的先后顺序执行。

    我们再看一张图:

    image.png
    我们在代码中使用dispatch_sync()函数给主队列添加了一个同步任务:
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"线程死锁");
        });
    }
    

    也就是说后添加的同步任务5是在viewDidLoad任务2之后,只有等待任务2执行完之后才能执行任务5,这就是串行队列的特点。但是任务5是一个同步任务,必须等任务5执行完才能执行其它任务,因此造成互相等待的死锁。

    再看一个例子

    image.png

    我们知道GCD分为同步任务和异步任务,最开始的例子是主线程的主队列,相当于是一个同步任务。而这个例子证明了,即便是在异步任务只要任务队列是串行队列,在串行队列的任务中再向队列添加同步任务,就会造成死锁,关键点不是同步还是异步,而是串行队列。

    总结

    dispatch_sync()函数会阻塞线程。当前队列是串行队列,任务必须顺序执行。在串行队列的任务A中给这个队列添加同步任务B,相当于说这个串行队列又多了一个任务B,任务B如果想要执行必须等待任务A执行完,但是任务B是同步任务,必须等任务B执行完才能执行其它任务,所以任务AB互相等待,造成死锁。

    相关文章

      网友评论

      • 码省理工0:大爱,很不错,感谢分享,也是对自己的一次总结和提升

      本文标题:iOS中的线程死锁

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