dispatch_sync死锁问题

来源:8-1 GCD相关面试问题

慕UI9212626

2018-04-13

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@".......");
    });
}

这样会死锁,这我一直都知道,但我之前都是这么理解的,因为sync是同步执行,会阻塞当前线程(主线程)等待block内容执行完在继续,而block内容恰恰是在主线程中执行,已经被阻塞了,所以导致了死锁。

但是我在听8-1章节的时候,听老师你说凡是dispatch_sync执行,不管是什么队列都是在当前线程执行,那么

- (void)viewDidLoad {
    [super viewDidLoad];    
    dispatch_sync(serial_queue, ^{
        NSLog(@".......");
    });
}

block中的内容也是在主线程中执行,那么也跟第一种情况一样了啊,sync阻塞了当前线程(主线程),block恰恰需要主线程中执行,死锁了岂不是?但事实是这种不会死锁。有点懵了。老师给分析一下吧。

写回答

3回答

慕慕6155927

2018-12-11

我来解释一下,看能不能解决一些人的疑惑,dispatch_get_main_queue()是个串行队列,viewDidLoad先加入串行队列中(假设队列序号1),里面的block后加入串行队列中(假设队列2),串行队列就必须1执行完,2才能执行;用了dispatch_sync,使得1要执行完,必须要2执行完才算完,但是又因为在串行队列中,2要执行必须等待1执行完了才轮到它,相互等待所以死锁。

至于下面dispatch_sync(serial_queue,.. 这个情况,我们还是叫viewDidLoad为队列任务1,block里的叫任务2, 跟上面的相同点在于,1要执行完必须要2执行完才算完,但是但是但是,2不需要等待1,只要2所在的serial_queue队列前面走完,就可以执行了,而只要2执行了,1就可以执行,所以不会死锁


2
0

香宝宝的小臭臭

2018-05-02

第二段代码分别是在主队列和自定义的串行队列进行的,所以不会死锁    死锁是由于队列(注意,是同一个队列内)引起的循环等待

2
0

于海

2018-04-13

课程有说是队列死锁 ,不是线程死锁,一定要区分开,所以换成自定义串行队列是没问题的,你可以亲自试一下

1
1
慕雪2298642
期待老师解释一下线程与队列之间的关系,网上看了好多文章,感觉解释的不是很清楚,难以理解。
2018-06-05
共1条回复

资深大牛带你深度剖析ios高级面试

从BAT/TMD名企真题入手,结合源码及应用,构建完整iOS知识体系

1749 学习 · 600 问题

查看课程