dispatch_async与dispatch_sync区别

概述

首先明确几个概念

  • 队列:队列分为串行和并行。串行队列按照A、B、C、D的顺序添加四个任务,这四个任务按照顺序执行,结束顺序也肯定是A、B、C、D,而并行队列同时执行这四个任务,完成的顺序因此也是随机的。
  • 异步执行(async)和同步执行(sync):使用dispatch_async调用一个block,这个block会被放到指定的queue_1队列尾等待执行,至于这个block是被并行还是串行执行,只和dispatch_async中的指定的queue_1有关,但是dispatch_async会马上返回。使用dispatch_sync同样也是把block放到指定的queue_2上执行,但是会等待这个block执行完毕后才返回,这期间会阻塞当前运行调用dispatch_async或dispatch_sync代码的queue(通常为main_queue)直到sync函数返回。

以打电话给查号台为例:

  • 同步:打电话给查号台,问某个地方的电话号码,接线员会告诉你稍等,然后为你查号,此时你的电话没有挂断,其他的电话也不能打进来,等到接线员查找到了你要找的电话号,告诉你后,才将电话挂断
  • 异步:打电话给查号台,问某个地方的电话号码,接线员知道了你的请求后,会立刻挂断电话,此时其他的电话可以打进来。然后开始为你查号。等到查找到了你要找的电话号,会再打电话通知你。

示例

异步
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执行完毕后才接着执行后面的代码

死锁

// 前提条件:当前的 queue 为 main_queue
dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"mainQueue_sync:1");
});

上述代码会造成死锁。原因:前提条件是当前 queue 为 main_queue。main_queue 为串行队列,在当前 queue 上调用 sync 函数。需要执行的 block 被放到当前 queue 的队尾等待被执行,因为这是一个串行的 queue,调用 sync 函数会阻塞当前队列,等待 block 被执行->这个 block 一直不会被执行-> sync 函数一直不返回,所以当前 queue 就被阻塞了,造成了死锁。
一般串行队列中 sync 到自身上会产生死锁,sync 到其他队列上一般不会产生死锁,如在自定义 queue 中 sync main_queue,等到 main_queue 执行完毕再继续执行操作。
说明

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

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

实例

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

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

注意

dispatch_sync 官方文档

As an optimization, dispatch_sync() invokes the block on the current thread when possible.
作为优化,如果可能,直接在当前线程调用这个block。

通过dispatch_sync添加的任务,在哪个线程添加就会在哪个线程执行。因此向并发队列添加的任务,没有开启新线程,而是在主线程执行的

参考

  1. GCD有关问题:dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"Hello ?");}); 死锁的原因
  2. Objective-C高级编程 P161 dispatch_sync
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容