iOS收藏

dispatch_async与dispatch_sync区别

2018-07-25  本文已影响290人  NapoleonY

概述

首先明确几个概念

以打电话给查号台为例:

示例

异步
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"async:1");
    });
NSLog(@"async:2");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"async:3");
    });
NSLog(@"async:4");

结果为

async:2
async:4
async:1
async:3

可以看出,dispatch_async将block追加到线程中后,并未等待,立刻执行后面的代码

同步
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"sync:1");
    });
NSLog(@"sync:2");
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"sync:3");
    });
NSLog(@"sync:4");

结果为

sync:1
sync:2
sync:3
sync:4

可以看出,dispatch_sync将block追加到线程中后,等待block执行完毕后才接着执行后面的代码

死锁

dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"mainQueue_sync:1");
});

上述代码会造成死锁。原因:main_queue为串行队列,在当前queue上调用sync函数,sync指定的queue也是当前queue。需要执行的block被放到当前queue的队尾等待被执行,因为这是一个串行的queue,调用sync函数会阻塞当前队列,等待block被执行->这个block一直不会被执行->sync函数一直不返回,所以当前queue就被阻塞了,造成了死锁。

说明

开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。

上述引用自苹果官方对GCD的说明,因此Dispatch_async和Dispatch_sync的作用是将block追加到队列中。这句话对于上述理解死锁有很大帮助。

实例

print(1)
serialQueue.async {
    print(2)
    serialQueue.sync {
        print(3)
}
print(4)
}
print(5)

分析:只会打印1,2,然后就死锁了。原因是列serialQueue.async的block1被异步追加到串行队列上后,开始执行,这个block1中又被同步追加了一个block2,此时serialQueue被阻塞,等待block2执行完毕,但是block1还未执行完毕,由于是串行队列,block只能按照追加的先后顺序一个一个执行:线程被阻塞->block1停止执行->block2等block1执行完毕->因此就造成了死锁。

参考

  1. GCD有关问题:dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"Hello ?");}); 死锁的原因
  2. Objective-C高级编程 P161 dispatch_sync
上一篇下一篇

猜你喜欢

热点阅读