美文网首页iOS面试题Ios进阶
GCD主线程上同步执行主队列方法卡死的解释

GCD主线程上同步执行主队列方法卡死的解释

作者: swifterlc | 来源:发表于2017-06-30 12:10 被阅读462次

我们都知道,在主线程上,同步执行,为主队列添加 task 会导致卡死。

到底该怎么理解呢?

第一 

主线程有一个特点:主线程会先执行主线程上的代码片段,然后才会去执行放在主队列中的任务。

第二

同步执行  dispatch_sync函数的特点:该函数只有在该函数中被添加到某队列的某方法执行完毕之后才会返回。即 方法会等待 task 执行完再返回


好了,有了这两点,死锁的问题就解决了。

注释里面分析了死锁原因 结果

卡死的原因已经说明清楚了。

现在来证明上面两点————————————

第一:主线程执行特点,先执行主线程上的代码,再执行主队列中的任务。

-------划重点了!  这里强调~~~~~>  主队列 ! 主队列 ! 主队列 !

如果是串行队列,在主线程上同步方法添加一个任务到串行队列。

首先我们知道程序不会死锁,不会开启线程,task 在主队列中顺序执行

不会死锁那说明,没有出现上面说的互相等待的问题,我们来分析一下。

首先,dispatch_sync 函数的特性没变

等待 task 执行完毕之后才能返回

既然,程序能正常运行,那么必然 dispatch_sync 函数等到了 task 的返回。

从结果输出的顺序看出,  同步执行串行队列的实质为

所以在上面会强调主队列等待,普通串行队列不等待主线程代码的执行。

主线程会先执行完主线程上的代码,然后再执行主队列中的方法!!

我们怎么证明呢?   要知道在主线程上同步为主队列添加 task 会死锁。

那么,我们在主线程上异步为主队列添加 task

task 被异步添加到主队列

结果好像是按照我们预期那样执行的,先执行主线程上代码在执行主队列中 task。 

可是,仅仅这样就判定主线程会先执行主线程中代码再执行主队列中的 task 还不准确。 

为什么?  首先,dispatch_async 函数的功能,我们都会想到,觉得是否开启新的线程去执行队列中的任务。其实还有一点,那就是这个函数本身不会阻塞线程的执行,不同于上述 dispatch_sync,dispatch_sync 会阻塞线程,知道里面的 task 执行完毕后才返回。这个特性在主线程乃至子线程都奏效。

所以,执行到dispatch_async函数时不等待 task 执行直接接着执行后面的代码。考虑到队列中 task 调用问题(这是需要 cpu 调度的,会消耗一定时间),我们在原代码基础之上,dispatch_async函数之后然线程 sleep 一会,看添加到主队列中的 task 是否真正在等待主线程上代码的执行。

结果和刚才一样,证明异步执行的时候,主队列的 task 会等待主线程的代码执行

那么我们就证明了,主线程确实会先执行完主线程上代码再执行主队列中的 task,  主队列又叫  全局串行队列。

我们解决死锁的方法,通常是把死锁方法放到子线程里面执行。

为什么现在就不会死锁了呢?

————————————————

子线程同步执行,一样阻塞, dispatch_async函数会阻塞下面 NSLog 方法进行输出,dispatch_async函数结束的时刻是里面 task 执行完毕的时刻,

dispatch_async将 task 放入主队列中,主队列等待主线程上代码执行完毕之后,再执行主队列中的 task ,主队列中的 task 执行完毕之后再跳出dispatch_async函数之后子线程最后的 NSLog 方法。

证明:

主线程代码进行 3s 的 sleep 结果和预期一样

接下来在子线程上把同步方法换成异步方法呢?

子线程不阻塞,接着执行,然后 sleep 3s ,执行主线程代码,最后是主队列task

MARK--------以后我们在见到dispatch_async 或者dispatch_sync时,除了要考虑他们是否会开启新的线程之外,还应该记住!————

dispatch_async不阻塞当前线程

dispatch_sync阻塞当前线程

相关文章

  • GCD主线程上同步执行主队列方法卡死的解释

    我们都知道,在主线程上,同步执行,为主队列添加 task 会导致卡死。 到底该怎么理解呢? 第一 主线程有一个特点...

  • GCD的学习笔记(One)

    并行和并发 GCD简介 GCD的任务 GCD的队列 GCD创建队列或获取队列的方法 任务的执行方式:同步执行(同步...

  • iOS 多线程GCD主线程上同步执行主队列方法卡死的解释

    我们都知道,在主线程上,同步执行,为主队列添加 task 会导致卡死。 到底该怎么理解呢? 第一 主线程有一个特点...

  • 20-多线程面试题

    1.下面代码执行结果 执行结果 - 会卡死 分析如下图 分析:同步执行 + 主队列会卡死当前线程,dispatch...

  • iOS-底层原理(21)-多线程面试题

    1.下面代码执行结果 执行结果 - 会卡死 分析如下图 分析:同步执行 + 主队列会卡死当前线程,dispatch...

  • ios线程概念运用

    GCD 整个使用的格式为: 先确定要创建的队列: (串行 并行) 队列中该线程是同步还是异步执行线程() 执行...

  • 多线程【转】

    文章目录GCD简介任务和队列GCD的使用步骤队列的创建方法任务的创建方法GCD的基本使用并行队列 + 同步执行并行...

  • GCD&NSOperationQueue

    GCD队列规律 同步派发任务只能在当前线程执行 异步派发任务可以在其他线程执行 串行队列任务只能在一个线程中执行 ...

  • GCD之简介

    1.多线程方案介绍 2.GCD中常用函数 同步执行 异步执行 3.GCD中常用队列 并发队列可以让多个任务并发(同...

  • gcd多线程任务与队列组合分析

    关于gcd中串行队列并行队列,以及同步任务和异步任务的花式嵌套,分析执行结果 多线程调试常用代码: gcd的任务 ...

网友评论

    本文标题:GCD主线程上同步执行主队列方法卡死的解释

    本文链接:https://www.haomeiwen.com/subject/suvbcxtx.html