GCD之死锁体会

1.先看下几句代码


dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);//串行线程队列

    dispatch_sync(serialqueue, ^{

        NSLog(@"1");

    });

    dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"2");

    });

2.前面博文写了GCD之死锁http://www.cnblogs.com/cuiyw/p/4369041.html写了这样一句:防死锁秘籍:不要在串行队列放dispatch_sync、dispatch_apply,这几天一直想着这句话,今天看用户自定义线程队列时,看到串行线程队列,所以就想着验证着句话是否正确,以为像上面那样写,两个都会死锁,运行了下发现并不像想象当中的那样。第一个能够输出,这让我大吃一惊,以为这句话难道不正确是错误的?有看了下同步异步,并敲代码体会了一下,发现是自己理解错误。

3.dispatch_sync、dispatch_apply这些都有体现同步。同步是阻塞当前线程,把参数中的block语句添加到参数中的线程队列中执行,待执行完毕后,返回阻塞的地方继续执行。

比如上面的两个同步:

第一个:当前运行的是主线程队列,mian queue,运行到dispatch_sync 时,主线程挂起,开始将block添加到自定义的串行线程队列中,待执行完毕后返回到当前主线程队列main queue。所以并不会产生死锁。

第二个:当前主线程执行到第二个同步时,阻塞,开始将block添加到主线程队列中,此时主线程队列等待block执行,而block这边等待主线程队列执行完,这样就产生了死锁。

4.再看如下代码:


dispatch_sync(queue,^{

        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"1");

        });

   });

   dispatch_sync(queue,^{

       dispatch_sync(dispatch_get_main_queue(), ^{

           NSLog(@"2");

       });

   });

上面两部分代码第一个不会死锁,而第二个会死锁。

个人分析理解,不一定正确。

第一个:主线程是串口线程队列,执行到sync的时候阻塞主线程队列,将block添加到全局线程队列中,全局线程队列开启一个线程,以异步的方式将最里面的block添加到主线程串口队列中,并返回,此时可以返回到原来阻塞的位置。

第二个:主线程执行到sync的时候阻塞主线程队列,将block添加到全局线程队列中,采用同步阻塞全局线程队列将最里面的block添加到主线程队列中,而此时主线程队列阻塞等待block的返回,而block则等待主线程队列执行完毕添加到主线程队列中,这样就死锁了。

时间: 2024-09-27 17:42:17

GCD之死锁体会的相关文章

GCD之死锁

GCD相当好用,但用不好就会死锁,始终要记着这样一句秘籍: 不要在串行队列放dispatch_sync.dispatch_apply 下面看几个例子 // 防死锁秘籍:不要在串行队列放dispatch_sync.dispatch_apply // 死锁 主线程调用dispatch_apply dispatch_async(dispatch_get_main_queue(), ^{ dispatch_apply(5, dispatch_get_main_queue(), ^(size_t i) {

12个iOS技术面试题及答案总结_IOS

前言 随着移动互联网科技不断的发展和创新,如今无论是公司还是开发者或设计师个人而言,面试都是一项耗时耗钱的项目,而面对iOS开发者及设计师在面试时可能会遇到的问题进行了筛选与汇总.下面我们一起来一下看看吧. 一.如何绘制UIView? 绘制一个UIView最灵活的方法就是由它自己完成绘制.实际上你不是绘制一个UIView,而是子类化一个UIView并赋予绘制自己的能力.当一个UIView需要执行绘制操作时,drawRect:方法就会被调用,覆盖此方法让你获得绘图操作的机会.当drawRect:方

GCD之异步同步体会

前面的博文也有写到同步异步,可能是看他人的博文,自己没有实验,感觉理解不深,所以就敲了些代码比较一下串行.并行分别对应的同步.异步. 1.首先创建串行.并行线程队列 dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);//串行线程队列 dispatch_queue_t concurrentqueue=dispatch_queue_create("con

C语言中多线程NSThread/NSOperation/GCD的使用

多线程NSThread的使用 NSThread每个NSThread对象对应一个线程,轻量级.NSThread:优点:NSThread比其他俩个轻量级,使用简单.                 缺点:需要自己管理线程的生命周期.线程同步.加锁.睡眠以及唤醒等.线程同步对数据的加锁会有一定的系统开销. NSThread的几种创建方式 //方式一:利用perform开启多线程,并且执行方法threadAction//    [self performSelectorInBackground:@sel

J2EE系统优化的几点体会

J2EE系统优化的几点体会(一.对象) 说到系统优化,是一个比较复杂的问题,涉及到软件的各个方面:需求.模块划分.数据库设计.程序编码以及一些特殊的优化方法如缓存技术等.而不同的应用又有其特殊的优化策略和技术.同时优化是贯穿系统从需求到实现再到维护的各个阶段的一项活动,而在各个阶段又有其不同的着眼点和具体方法. 本文立足于具体的J2EE项目实践,结合一些已有的优化条例,提出自己的一些体会,也算是作为一次对实际项目经验教训的总结. 优化一般意义上说是提高已有系统的性能,减少如内存.数据库.网络带宽

iOS学习之GCD

GCD(Grand Central Dispatch),是 Apple 开发的一个多核编程的解决方法.该方法在 Mac OS X 10.6 雪豹中首次推出,并随后被引入到了 iOS4.0 中.GCD 是一个替代诸如NSThread,NSOperationQueue, NSInvocationOperation 等技术的很高效和强大的技术. GCD 和 block 的配合使用,可以方便地进行多线程编程. 1.优势: 1)  苹果官方为多核的并行运算提出的解决方案. 2)  会自动利用更多的CPU内

IOS开发之多线程 -- GCD的方方面面

前言:这篇GCD的博文是本人阅读了很多海内外大神的关于GCD的文章,以及结合之前自己对GCD的粗浅的认识,然后取其精华,去其槽粕,综合起来的笔记,而且是尽可能的以通熟易懂的并且是正确的理论论述方式呈现给读者,同时也是讲大神博客中有的深涩的理论理解的通熟易懂转述给读者,已经是尽可能的让读者深入理解和掌握多线程的知识以及GCD的使用技术.最后的附录中,我将会给出所有本人阅读的大神写的关于多线程或者是GCD的文章链接,大家感兴趣的,可以去参考和学习.也许,看我的这篇就够了,因为我就是参考他们的,嘻嘻.

GCD 深入理解(一)

本文由@nixzhu翻译至raywenderlich的<grand-central-dispatch-in-depth-part-1> 虽然 GCD 已经出现过一段时间了,但不是每个人都明了其主要内容.这是可以理解的:并发一直很棘手,而 GCD 是基于 C 的 API ,它们就像一组尖锐的棱角戳进 Objective-C 的平滑世界.我们将分两个部分的教程来深入学习 GCD .   在这两部分的系列中,第一个部分的将解释 GCD 是做什么的,并从许多基本的 GCD 函数中找出几个来展示.在第二

漫谈GCD

多线程是程序开发中非常基础的一个概念,大家在开发过程中应该或多或少用过相关的东西.同时这恰恰又是一个比较棘手的概念,一切跟多线程挂钩的东西都会变得复杂.如果使用过程中对多线程不够熟悉,很可能会埋下一些难以预料的坑. iOS中的多线程技术主要有NSThread, GCD和NSOperation.他们的封装层次依次递增,其中: NSThread封装性最差,最偏向于底层,主要基于thread使用 GCD是基于C的API,直接使用比较方便,主要基于task使用 NSOperation是基于GCD封装的N