关于dispatch_sync死锁问题

首先,我们来看下下面一个例子:
代码:(串行队列里同步线程嵌套)
    NSLog(@"haha");
    dispatch_queue_t queue = dispatch_queue_create("test", nil);
    dispatch_sync(queue, ^ {
        NSLog(@"xxoo0");
        dispatch_sync(queue, ^ {
            NSLog(@"xxoo1");
        });
        NSLog(@"xxoo2");
    });
运行结果:

2014-08-25 14:30:24.440 test[4424:60b] haha
2014-08-25 14:30:24.441 test[4424:60b] xxoo0

在test串行队列中,有两个同步线程嵌套导致第二个同步线程运行不了,产生了死锁。
原因是:在串行队列中,第二个同步线程要执行,必须等待第一个同步线程执行完成后才可进行,但是第一个同步线程要执行完又得等待第二个同步线程执行完,因为第二个同步线程嵌套在第一个同步线程里,这就造成了两个同步线程互相等待,即死锁。
特别强调:是在串行队列里!


    dispatch_queue_t queue = dispatch_queue_create("test", nil);
这行代码中,第二个参数为nil值,相当与值为DISPATCH_QUEUE_SERIAL,即为串行的。如果把值改成DISPATCH_QUEUE_CONCURRENT,即为并行的,就不会导致两个同步线程死锁。或者使用dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)也行,因为dispatch_get_global_queue是并行队列。

ok,我们来看第二个例子:

代码:(主线程里的同步线程)

    NSLog(@"haha");
    dispatch_sync(dispatch_get_main_queue(), ^ {
        NSLog(@"xxoo");
    });
运行结果:

2014-08-25 15:01:58.922 test[4797:60b] haha

结果还是死锁,这个例子其实和第一个例子是类似的,主线程其实就是在一个串行队列里的,我们写的这个同步线程就相当与第一个例子的第二个嵌套的同步线程,因为这个同步线程是在主线程里写的,就相当于嵌套在主线程里的。

所以,对于
dispatch_sync(queue, ^{});
这行代码的意义可以概括为: 会阻塞当前线程等待串行queue中的所有任务执行完成后再向下执行。

不要让任何事成为你不去学习的理由
原文地址:https://www.cnblogs.com/jgl-blog/p/5110778.html