美文网首页
底层20:多线程-同步/异步/并发/串行

底层20:多线程-同步/异步/并发/串行

作者: 张无奈 | 来源:发表于2020-09-08 11:00 被阅读0次

    GCD两种常用的函数:

    GCD中有2个用来执行任务的函数

    用同步的方式执行任务:dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

    queue:队列

    block:任务

    用异步的方式执行任务:dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

    GCD是开源的:https://github.com/apple/swift-corelibs-libdispatch

    GCD队列:

    并发队列(Concurrent Dispatch Queue):

    可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务);

    并发功能只有在异步函数下才有效。

    串行队列:让任务一个接着一个地执行(一个任务执行完后,再执行下一个任务)

    容易混淆的术语:

    有4个术语比较容易混淆:同步、异步、并发、串行

    同步和异步主要影响:能不能开启新的线程

    同步:在当前线程中执行任务,不具备开启新线程的能力。

    异步:在新的线程中执行任务,具备开启新线程的能力

    并发和串行主要影响:任务的执行方式

    并发:多个任务并发(同时)执行

    串行:一个任务执行完毕以后,再执行下一个任务(主队列也是一个串行队列)

    各种队列的执行效果

    死锁实例分析

    实例1:

    分析:是在主队列中执行,因为是同步并且在viewDidLoad方法中,所以在是在主线程中执行,队列存在先进先出的原则,首先要执行完viewDidLoad方法才能执行任务2,但是任务2又在viewDidLoad方法中,相当于任务2和3相互等待造成死锁。

    实例2:

    分析:因为在主线程中执行,是串行队列串行执行任务,而异步刚好不要求立马在当前线程同步执行任务,所以打印顺序:执行任务1、执行任务3、执行任务2

    实例3:

    分析:发现任务3和任务4跟实例1一样。

    实例4: 如下只要创建了第二个队列替换,不管是串行还是并发 都不会产生死锁

    实例5: 换成并发队列,任务3,4不会等待,并发执行。

    总结:使用 sync函数  往 当前串行队列  中添加任务,会卡住当前的串行队列(产生死锁)

    分析:全局队列打印地址一样,说明全局队列始终是同一个队列(也可以理解为全局队列相当于是一个全局变量,始终是同一个);后面自行创建的并发队列,地址不一样,说明是不同的队列。

    注意:

    [self performSelector:@selector(test) withObject:nil afterDelay:.0];的本质是往RunLoop中添加定时器,而子线程默认没有启动runLoop。所以需要手动启动:

    [self performSelector:@selector(test) withObject:nil]跟它是不一样的,没有关系到RunLoop,如果它不启动照常打印。

    相关文章

      网友评论

          本文标题:底层20:多线程-同步/异步/并发/串行

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