ios - 关于一个多线程的问题。
天蓬老师
天蓬老师 2017-04-17 17:57:51
[iOS讨论组]

不明白为什么结果只输出:1
即使把NSLog(@"3");这句话删掉也程序也卡住,不往下执行了。
有人能分析下?

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(1)
巴扎黑

首先你这问题不是很严谨。你这段代码死锁的条件是,整段代码得在主线程上运行,而如果在一个其他的线程队列上运行,都是不会有问题的,不管它是串行的还是并行的。

比如这样:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
    NSLog(@"3");
});

或者这样:

dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
    NSLog(@"3");
});

你上面提到的之所以会造成死锁,原因在于,你在一个串行队列中,同步的向此队列添加了一个block块。

实际上,就是这样:

dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
    NSLog(@"1");
    dispatch_sync(serialQueue, ^{
        NSLog(@"2");
    }); 
    NSLog(@"3");
});

简单点说,问题在于,串行队列是串行执行的,在这个串行队列上有三个任务,分别是:

  1. NSLog(@“1”)

  2. dispatch_sync

  3. NSLog(@“3”)

在走到第2步的时候,发现需要给整个队列添加一个任务,就是 NSLog(@"2") 。这时候,执行的任务就变成了:

  1. NSLog(@“1”)

  2. dispatch_sync

  3. NSLog(@“3”)

  4. NSLog(@“2”)

然后,因为是同步的,所以:

  • 线程就要等 NSLog(@"2") 执行完了才能往下走,去执行NSLog(@“3”)

  • 但是NSLog(@"2")执行之前需要执行 NSLog(@“3”)

  • NSLog(@“3”)又需要等 NSLog(@"2")执行完了。

然后,就死锁了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号