dispatch_sync 的分析

作者: 酸菜Amour | 来源:发表于2016-08-30 10:00 被阅读855次

dispatch_sync 函数同步任务处理函数,这里我将根据几种常见的情况来分析这个函数的运作机制,这几种情况分别是:

1.在主线程中将同步任务压进主队列中(死锁):

dispatch_sync 在 libdispatch 是 封装成 dispatch_sync_f 的:

dispatch_sync_f

里面有个 slowpatch(x) 和 fastpatch(x) 的宏定义,其实这两个宏定义完全没什么作用,就是返回 X 。

现在分析一下,在主线程中将同步任务压进主队列会发生什么,首先主队列的宽度是1的,所以它会进入 dispatch_barrier_sync_f 函数中:

dispatch_barrier_sync_f

在 if 里面,它会判断进入的队列是否有其他任务,是否被挂起,是否能加锁,很明显,主队列中还有其他任务(我们现在执行的函数就是主队列的任务),则会进入 _dispath_barrier_sync_f_slow 函数中:

_dispath_barrier_sync_f_slow

简单说一下这个函数里面的内容,这个函数就是封装了一个信号量,然后将信号量压进队列中,然后在这个函数中等待那个信号量,如果主队列中会出现什么情况?信号量被压进主队列中,然后信号量的上一个任务刚好是这个函数,永远都执行不到信号量的函数,然后死锁就愉快的发生了。

2.向一个串行队列中压进一个同步任务:

在上面的分析,会跑到 dispatch_barrier_sync_f ,因为这个串行队列是刚创建的,里面不可能有其他任务,所以这个任务会直接执行。

3.向一个并发队列中压进一个同步任务:

并发队列宽度大于1,在 dispatch_sync_f 函数中,会跳过 _dispath_barrier_sync_f_slow 函数,然后判断这个并发队列中是否存在其他任。

(1).如果不存在其他任务,会判断这个任务是用户自创建的队列还是全局队列,如果是用户自己创建的队列,直接执行任务,如果是全局队列,则唤醒这个队列,进入 _dispatch_sync_f_slow 函数,这里简单说一下这个函数,这个函数是会将信号量压进它的形参队列中,然后等待这个信号量,所以如果这是个全局队列,则很快等待这个信号量(在其他线程会释放这个信号量,表明这个全局队列的线程开启成功),然后直接执行任务;

(2).如果队列中存在其他任务,则直接进入 _dispatch_sync_f_slow 函数,等待这个队列中的其他任务完成(信号量的方式),然后执行这个任务。

我们从上可以看出,我们执行同步任务的时候,从来都没有压进队列中,不需要经过其他方式的调度,直接在 dispatch_sync_f 函数中运行任务的。

相关文章

  • dispatch_sync 的分析

    dispatch_sync 函数同步任务处理函数,这里我将根据几种常见的情况来分析这个函数的运作机制,这几种情况分...

  • GCD死锁案例解析

    参考:http://ios.jobbole.com/82622/ 案例一 分析:dispatch_sync 执行后...

  • dispatch_sync()死锁问题个人疑问

    分析: 当前dispatch_sync()函数在主线程中调用,可以用 NSLog(@"%@",[NSThread ...

  • 2018 多线程

    1. dispatch_async/dispatch_sync dispatch_sync: 同步/阻塞当前的...

  • GCD学习(六) dispatch_async 和dispatc

    GCD学习(六) dispatch_async 和dispatch_sync dispatch_sync(),同步...

  • gcd 死锁

    同步、异步:使用dispatch_sync(同步) :dispatch_sync 方法会被加入当前队列,而且dis...

  • GCD底层

    一、同步执行dispatch_sync 1.1 锁的原因 我们都知道,当使用dispatch_sync在串行队列上...

  • iOS dispatch_sync

    dispatch_sync Declaration Parameters queue block Discussion

  • GCD中的dispatch_sync、dispatch_sync

    平常开发中会经常用gcd做一下多线程任务,但一直没有对同步、异步任务在串行、并行队列的执行情况做个全面的认识,今天...

  • 主线程死锁问题

    dispatch_sync(dispatch_get_main_queue(), ^(){ NSLog(@"...

网友评论

  • Scott丶Wang:在 if 里面,它会判断进入的队列是否有其他任务,是否被挂起,是否能加锁,很明显,主队列中还有其他任务(我们现在执行的函数就是主队列的任务),则会进入 _dispath_barrier_sync_f_slow 函数中 这里的“主队列中还有其他任务”是什么时候赋值的???
  • redSnake:有人说你曲高和寡,其实也是包含了晦涩难懂,技高一筹的意思啊,GCD底层都被你分析了啊哈哈

本文标题:dispatch_sync 的分析

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