请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

dispatch_sync死锁问题

- (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

3回答

慕慕6155927 2018-12-11 00:05:57

我来解释一下,看能不能解决一些人的疑惑,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 回复 有任何疑惑可以回复我~
香宝宝的小臭臭 2018-05-02 00:20:43

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

2 回复 有任何疑惑可以回复我~
于海 2018-04-13 07:04:05

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

1 回复 有任何疑惑可以回复我~
  • 期待老师解释一下线程与队列之间的关系,网上看了好多文章,感觉解释的不是很清楚,难以理解。
    回复 有任何疑惑可以回复我~ 2018-06-05 00:23:25
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信