美文网首页
iOS gcd看我就够了

iOS gcd看我就够了

作者: 智人一千 | 来源:发表于2019-09-26 11:06 被阅读0次

gcd是iOS中多线程的一种技术,下面我们来看看gcd的用法

同步&异步

同步

同步执行:字面意思,同步执行就是执行完任务1,再执行任务2任务1不执行完任务2就等着。
对应函数dispatch_sync,这个函数会把一个block加入到对应队列,只有block执行完,这个函数才会返回。因此block执行完之前,调用dispatch_sync的线程是阻塞的。代码如下:

    //dispatch_sync同步执行
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"任务1");
    });
    NSLog(@"任务2");
同步效果

异步

对应函数dispatch_sync,同样该函数会把一个block添加到队列中。和同步执行不同的是,该函数会立即返回,不用等block执行完。

    //dispatch_async异步执行
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"任务1");
    });
    NSLog(@"任务2");
异步执行效果

串行队列

通过DISPATCH_QUEUE_SERIAL修饰,或者主队列dispatch_get_main_queue,串行队列一定按照FIFO(先来后到的顺序)执行。串行队列中,执行当前任务时,该任务之前的人物都已执行完。对每一个串行队列,系统都会为这个队列创建唯一线程执行任务

并行队列

通过DISPATCH_QUEUE_CONCURRENT修饰,并行队列按照FIFO(先进先出)开始执行,注意是开始,结束时间是不确定的。并发队列中的任务:GCD会动态分配多条线程来执行。具体几条线程取决于当前内存使用状况,线程池中线程数等因素。

只有执行async异步任务才会开辟新线程,在async任务中:
1.主队列dispatch_get_main_queue下不会开辟线程,还是主线程;
2.串行队列开辟唯一线程;
3.并行队列开辟至少一条线程,系统自动分配;

死锁DeadLock

对应下面代码

1.首先aqueue是个串行队列,此时线程是主线程main thread;
2.在执行同步方法dispatch_sync后,会把block添加到aqueue队列,block不执行完之前,此时对应的线程main thread处于阻塞状态;
3.block内执行任务1dispatch_sync,而任务1dispatch_sync是添加在aqueue上的;
4.从上面我们知道此时aqueue对应的线程main thread处于阻塞状态,所以任务不会被执行,这就是死锁;

    //创建串行队列DISPATCH_QUEUE_SERIAL,注意dispatch_get_main_queue()s也是串行队列
    dispatch_queue_t aqueue = dispatch_queue_create("aqueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(aqueue, ^{
        NSLog(@"这种情况会发生死锁:%@",[NSThread currentThread]);
        //任务1
        dispatch_sync(aqueue, ^{
            NSLog(@"任务1:%@",[NSThread currentThread]);
        });
        //任务2
        NSLog(@"任务2:%@",[NSThread currentThread]);
    });
死锁运行效果

从运行效果可以看出,block没走完(图片里停在44行),线程处于阻塞状态,在阻塞的线程里执行任务1,造成死锁。

死锁的另一种情况:

    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"这种情况是死锁");
    });

代码内,默认是在主线程主队列下运行的,此时执行同步函数dispatch_sync,把block添加到主线程。我们上面知道同步函数dispatch_sync在串行队列(此时的主队列是串行队列)是阻塞线程的,也就是说主线程被阻塞了,此时block永远不会被执行,造成死锁。

这种情况为什么不发生死锁?

    //在主线程主队列下,在串行队列queue下添加同步任务
    dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
    NSLog(@"这种情况不会发生死锁,因为此处任务是在一个新的队列里");
    });

死锁发生条件:在串行队列中,向该串行队列添加同步任务。(强调一下,是同一队列)

demo地址
未完待续~

相关文章

  • 学习GCD看我就够了

    学习GCD看我就够了 学习GCD看我就够了

  • iOS gcd看我就够了

    gcd是iOS中多线程的一种技术,下面我们来看看gcd的用法 同步&异步 同步 同步执行:字面意思,同步执行就是执...

  • 学习GCD看我就够了

    什么是多线程? 计算机在运行一段程序的时候,会把该程序的CPU命令列配置到内存中,然后按照顺序一个一个执行命令列,...

  • 学习GCD看我就够了

    什么是多线程?计算机在运行一段程序的时候,会把该程序的CPU命令列配置到内存中,然后按照顺序一个一个执行命令列,这...

  • iOS多线程之GCD详解(看我就够了)

    简介 什么是GCD全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”纯C语言,提供了非...

  • 线程GCD

    本文只是学习他人知识点进行一定的总结巩固自己的理解学习GCD看我就够了iOS多线程全套 一、多线程的定义 计算机在...

  • IOS 多线程知识学习

    学习多线程,转载两篇大神的帖子,留着以后回顾!第一篇:关于iOS多线程,你看我就够了 第二篇:GCD使用经验与技巧...

  • GCD任务、队列、线程看我就够了

    GCD开源地址[https://opensource.apple.com/release/macos-10141....

  • iOS faceID看我就够了

    需要最低系统支持8.0以上,如果是FaceID至少IOS11以上. 第一步:首先引入头文件。 记得plist文件...

  • iOS 多线程:『GCD』详尽总结(多线程看这里就够了)

    iOS 多线程:『GCD』详尽总结(多线程看这里就够了) https://www.jianshu.com/p/2d...

网友评论

      本文标题:iOS gcd看我就够了

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