1.先看下几句代码

1
2
3
4
5
6
7
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.再看如下代码:

1
2
3
4
5
6
7
8
9
10
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则等待主线程队列执行完毕添加到主线程队列中,这样就死锁了。

GCD之死锁体会的更多相关文章

  1. iOS多线程开发之GCD(死锁篇)

    上篇和中篇讲解了什么是GCD,如何使用GCD,这篇文章将讲解使用GCD中将遇到的死锁问题.有兴趣的朋友可以回顾<iOS多线程开发之GCD(上篇)>和<iOS多线程开发之GCD(中篇) ...

  2. GCD之死锁

    GCD相当好用,但用不好就会死锁,始终要记着这样一句秘籍: 不要在串行队列放dispatch_sync.dispatch_apply 下面看几个例子 1 2 3 4 5 6 7 8 9 10 11 1 ...

  3. iOS多线程——GCD与NSOperation总结

    很长时间以来,我个人(可能还有很多同学),对多线程编程都存在一些误解.一个很明显的表现是,很多人有这样的看法: 新开一个线程,能提高速度,避免阻塞主线程 毕竟多线程嘛,几个线程一起跑任务,速度快,还不 ...

  4. GCD 容易让人迷惑的几个问题

    写在开头: 本文旨在阐述一些大家容易产生迷惑的GCD相关内容,如果是需要了解一些GCD概念或者基础用法,可以看看这两篇文章:GCD 扫盲篇.巧谈GCD . 目录: 迷惑一:队列和线程的关系 迷惑二:G ...

  5. 追踪app崩溃率、事件响应链、Run Loop、线程和进程、数据表的优化、动画库、Restful架构、SDWebImage的原理

    1.如何追踪app崩溃率,如何解决线上闪退 当 iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈 跟踪信 ...

  6. 那些著名或非著名的iOS面试题-前编

    1.如何追踪app崩溃率,如何解决线上闪退 当iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈跟踪信息和 ...

  7. BAT面试的准备—iOS篇

    本文主要用于记录在准备BAT面试中关于iOS遇到的问题和做一些相关面试题的笔记 iOS网络层设计 1.网络层和业务层的对接设计 使用哪种交互模式来和业务层对接 : 使用Delegate为主,目的是为了 ...

  8. 多线程下载图片,滑动tableView崩溃--资源抢夺问题

    最近练习使用NSoperation模拟SDWebImage下载图片,发生了崩溃的问题,还专门写博客记录这件事情: http://www.cnblogs.com/tufei7/p/7074030.htm ...

  9. iOS知识点汇总

    1.怎样追踪app崩溃率.怎样解决线上闪退 当iOS设备上的App应用闪退时.操作系统会生成一个crash日志.保存在设备上.crash日志上有非常多实用的信息,比方每个正在运行线程的完整堆栈跟踪信息 ...

随机推荐

  1. elasticsearch报错expected <block end>, but found BlockMappingStart解决方法

    我用的是elasticsearch2.4.0,在修改完配置文件就出现类似格式 expected <block end>, but found BlockMappingStart...... ...

  2. 使用xorm工具,根据数据库自动生成 go 代码

    使用xorm工具,根据数据库自动生成 go 代码 引入 使用 golang 操作数据库的同学都会遇到一个问题 -- 根据数据表结构创建对应的 struct 模型.因为 golang 的使用首字母控制可 ...

  3. @Autowired和@Resource的区别是什么?

    @Autowired 与@Resource: 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配 ...

  4. Servlet使用简介

    Servlet的使用基本包含三个步骤: 1.继承HttpServlet 或实现Servlet 接口 (根据源码分析最终都是对servlet接口的实现) 2.配置地址: 配置web.xml 或者用注解的 ...

  5. 设置input框文字垂直居中和宽度

    input { solid #999;height:22px; background:#ffffff; line-height:22px; margin:0px; padding:0px;/*表单输入 ...

  6. jmeter系列------变量的提取

    为了保证脚本的移植性,需要把一些变量提取出来,变量主要分为2类 1.一类是公用变量(全局变量),包括:IP.port.附件路径.CSV路径等,通常是使用用户定义的变量 组件 2.另一类是测试变量一般作 ...

  7. TC358749XBG:HDMI转MIPI CSI芯片简介

    TC358749XBG是一颗HDMI转MIPI CSI功能的视频转换芯片,分辨率:1920*1080,电源3.3/1.8/1.2,通信方式:IIC,封装形式BGA80

  8. MVC配置伪静态

    提出需求 伪静态能提高搜索引擎收录,还不影响硬盘寿命,是一个不错的选择,但是会增加CPU和内存开销,由于时候也需要实现伪静态. web.config配置 <system.webServer> ...

  9. Apple公司开发者账号申请(2017包含邓白氏码申请)

    1.首先看需要那种账号 2.这个需要的是公司开发者账号,首先我们注册一个普通apple账号 打开网址 https://developer.apple.com 进入点击Account 进入登录页面,点击 ...

  10. ln命令详解

    ln命令 (全称:link) ln命令用来为文件创建一个连接,类似于Windows的快捷方式,连接类型分为硬连接和软连接(符号连接)两种,默认的连接类型是硬连接.如果要创建符号连接必须使用" ...