美文网首页
二、任务、队列之间的嵌套

二、任务、队列之间的嵌套

作者: 人间四月天_Andy | 来源:发表于2018-09-13 12:01 被阅读0次

    此文章只做学习笔记之用,如有错误,欢迎留言批评指正!!!


     GCD之任务、队列之间的相互嵌套

    注意:

    同步、异步:针对的是线程

     串行、并行:针对的是队列

    一条线程同一时间只能执行一个任务,同步的话,不会开辟线程,所以任务只会在主线程里边进行,因此,同步任务里边,不管是串行队列还是并行队列,都只能是一个任务完成之后,才会执行下个任务。

    一、 同步并发嵌套异步

    同步并发嵌套异步1 同步并发嵌套异步2

    分析:

    1.    先输出begin (这个毋庸置疑)

    2.    接下来,是一个同步并发任务(简称block1),而同步任务会阻塞当前线程,所以只有当block里边的任务执行完之后才会执行 任务end 所以end 排在最后边

    3.    block1中有包含三个小任务 任务1、block2、任务3,而block2中只有一个任务2

    4.    block1中任务的执行顺序肯定是先输出任务1,这个就不啰嗦了。接下来是block2,而block2 是一个异步的,所以不会阻塞当前线程,由于是异步的,所以可能会开辟一条新线程运行任务2

    5.    因为异步没有阻塞当前线程,所以block2这个任务有没有完成不会影响任务3的执行,因此任务3 可能会在任务2之前输出。当然也有可能任务2在前,任务3在后。

    6.    接下来上图,在任务3之前模拟一个耗时操作

    添加耗时操作 输出结果

    结论:begin 任务1 任务3 任务2 end 或者 begin 任务1 任务2 任务3 end 


    二、 同步并发嵌套同步

    同步并发嵌套同步

    分析:应为都是同步,所以每个任务都不会开辟新线程 都会阻塞当前线程,任务一个接一个执行,所以无论是否添加耗时操作,结果都一样

    结论:输出结果就是 begin ->任务1 ->任务2 ->任务3 ->end


    三、同步串行嵌套异步

    同步串行嵌套异步

    队列是串行队列

    同步串行队列函数–>block1

    异步串行队列函数–>block2

    分析:

    1.    先输出begin 

    2.    接下来碰到一个同步函数(block1),不会开辟线程,阻塞当前线程,打印 任务1

    3.    然后碰到异步函数(block2)会开辟新线程,所以会把这个异步串行队列函数(也就是block2)放到子线程中去运行,因为是串行队列,所以在同步串行队列函数(也就是block1)运行完之前block2任务不会执行,因此会先打印 任务3

    4.    block1 执行完成后,可能会打印end 也可能会打印任务2 这两个的打印顺序是不可控的

    结果1

    在end之前添加一个耗时操作,则打印结果是这样的:

    结果2

    四、     同步串行嵌套同步

    异步并发嵌套异步

    运行结果:

    运行结果

    很明显:死锁,也就是两个任务相互等待(block2 等待block1 完成,而block1 又在等待block2 完成)


    五、     异步串行嵌套异步

    异步串行嵌套异步1 异步串行嵌套异步2

    分析:

    1.    begin 先输出

    2.    接下来是一个异步串行队列函数(block1),由于是异步的,不会阻塞当前线程,所以block1 和end 的输出顺序就是不可控的,同理block2 和end的输出顺序也是不可控的。

    3.    因为是串行队列,任务会一个一个执行,任务2的输出一定是在任务3后边,即使任务3前边添加了耗时操作


    结论:

     由于是异步的所以输出顺序就会变得不可控,下面列出集中输出顺序,以供参考:

    ①.     begin – 任务1 – 任务3 – end – 任务2

    ②.     begin – end – 任务1 – 任务3 – 任务2

    ③.     begin – 任务1 – 任务3 – 任务2 – end 

    ④.     begin – 任务1 – end – 任务3 – 任务2 


    六、     异步串行嵌套同步(死锁)

    异步串行嵌套同步(死锁)

    分析:

    1.    begin

    2.    接下来遇到异步函数,将任务1、同步线程(block2)、任务3 添加到了串行队列中。由于是异步线程,所以end 可以不必等待直接block1中的任务完成

    3.    所以 end 和任务1 的输出位置就是不可控的

    4.    任务1 输出之后,遇到同步线程,将任务2添加到串行队列中

    5.    由于任务3 比任务2 先添加到串行队列,所以,任务2 要等到任务3完成之后,才能执行。但是任务2是所在的同步线程会发生阻塞,所以任务3 又必须等任务2执行完成之后再执行,因此,就会陷入到无限等待中,造成死锁。

    相关链接:http://ios.jobbole.com/82622/(此文介绍的比较通俗易懂,没看明白的小伙伴可以查看此篇文章)


    七、     异步并发嵌套同步

    异步并发嵌套同步

    分析:

    1.    begin ,接下来是遇到一个异步并发队列,所以end 的输出则不受影响

    2.    在block1中 一次添加了任务1 、同步并发队列(block2)、任务3

    3.    然后输出任务1 接下来遇到一个同步线程,将任务2添加到并发队列中,由于同步会阻塞当前线程,所以任务3 必须等到任务2输出之后,才能输出,即使在任务2里边添加耗时操作,任务3的输出一定是在任务2之后

    4.    end的输出顺序不可控


    八、     异步并发嵌套异步

    异步并发嵌套异步

    分析:

    1.    begin,接下来是一个异步

    2.    所以end 的输出顺序不可控

    3.    由于都是异步的并且都是并发队列,所以任务1、任务2、任务3的顺序也都是不可控的,但是任务1肯定是在任务2、任务3前边

    相关文章

      网友评论

          本文标题:二、任务、队列之间的嵌套

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