GCD基础

作者: 曼谷第一开膛手 | 来源:发表于2018-08-17 16:11 被阅读15次

什么是多线程?

计算机在运行一段程序的时候,会把该程序的CPU命令列配置到内存中,然后按照顺序一个一个执行命令列,这样1个CPU执行的CPU命令列为一条无分叉路径就是线程。
而有多条这样的执行指令列的路径存在时即为多线程。
OS实现多线程有4种方法

  • pthreads
  • NSThread
  • GCD
  • NSOperation & NSOperationQueuef
一、Dispatch Queue和线程的关系

什么是Dispatch Queue?

如其名称,是执行处理的等待队列。当我们通过dispatch_async等函数把Block加入Dispatch Queue后,Dispatch Queue按照追加的顺序(FIFO)执行处理。 1293297-4e51a7482a9a6d7e.png

Dispatch Queue的种类

  • Serial Dispatch Queue(串行队列) ——等待现在执行中处理结束再加入队列
  • Concurrent Dispatch Queue(并发队列) ——不等待现在执行中处理结束,直接加入队列 1293297-1ab53bc44e6eea1f.png
    1293297-4868cfbbcf93621c.png

Serial Dispatch Queue

dispatch_queue_t serial_queue = dispatch_queue_create("come.tanpei", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serial_queue, ^{
        NSLog(@"block 1");
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"block 2");
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"block 3");
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"block 4");
    });

2017-09-27 11:43:40.230126+0800 aegewgr[4327:1296458] block 1
2017-09-27 11:43:40.230335+0800 aegewgr[4327:1296458] block 2
2017-09-27 11:43:40.230461+0800 aegewgr[4327:1296458] block 3
2017-09-27 11:43:40.230548+0800 aegewgr[4327:1296458] block 4

这里Serial Dispatch Queue只会使用一个线程,因为它是串行队列,只会当一个处理执行完了才会将下一个任务交给线程处理。

Concurrent Dispatch Queue

dispatch_queue_t concurrent_queue = dispatch_queue_create("come.tanpei", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurrent_queue, ^{
        NSLog(@"block 1");
    });
    dispatch_async(concurrent_queue, ^{
        NSLog(@"block 2");
    });
    dispatch_async(concurrent_queue, ^{
        NSLog(@"block 3");
    });
    dispatch_async(concurrent_queue, ^{
        NSLog(@"block 4");
    });

2017-09-27 11:45:09.057505+0800 aegewgr[4349:1304484] block 3
2017-09-27 11:45:09.057505+0800 aegewgr[4349:1304483] block 1
2017-09-27 11:45:09.057522+0800 aegewgr[4349:1304486] block 4
2017-09-27 11:45:09.057505+0800 aegewgr[4349:1304485] block 2

block的执行完成
是随机的,因为他们虽然是按顺序把任务提交给线程,但是因为不需要等待前一个任务执行,所以几乎是同时交给线程处理的。所以这里会使用多个线程,而具体线程数的多少由XNU内核决定。

二、Dispatch Queue的使用

1、获取队列

在使用Dispatch Queue的时候我们可以通过dispatch_queue_create函数创建队列,也可以获取系统给我们提供的队列。系统给我们提供了两种队列 1293297-a6af209dcbce45ed.png.jpeg
2、同步与异步
  • dispatch_async表示异步:将指定的Block”非同步“加入Dispatch Queue,不做任何等待 1293297-df4abfc994331c9c.png
  • dispatch_sync表示同步:将指定的Block”同步“的加入Dispatch Queue,在Block结束之前,dispatch_sync函数会一直等待


    1293297-97eb917212a124bc.png

    3、死锁
    由于dispatch_sync会等待Block执行结束才会继续往下执行,所以会产生死锁的情况
    我们直接在主线程中同步加入一个Blcok:

dispatch_queue_t main_queue = dispatch_get_main_queue();
    dispatch_sync(main_queue, ^{
        NSLog(@"main queue");
    });
    NSLog(@"go on");

无任何输出,程序直接卡死了。这就是造成了死锁。
因为该源代码在main_queue(主线程)中加入一个加入一个指定的Block,并等待其执行结束。而由于main_queue是一个串行队列,它要等当前线程中的任务处理完后才会把队列中的任务提交到主线程,而主线程又在等待这段代码执行,所以造成了相互等待,就产生了死锁。(而并发队列不会产生死锁)

dispatch_queue_t global_queue = dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT);
    dispatch_sync(global_queue, ^{
        NSLog(@"global_queue out");
        dispatch_sync(global_queue, ^{
            NSLog(@"global_queue in");
        });
    });

2017-09-27 16:11:56.332317+0800 aegewgr[4723:1590202] global_queue out
2017-09-27 16:11:56.332446+0800 aegewgr[4723:1590202] global_queue in

所以产生死锁的话一般都是在串行队列中并且是在一个线程中同步往这个线程提交一个Block。

相关文章

  • iOS 开发之 GCD 基础

    iOS 开发之 GCD 基础 本文主要为 GCD 的 队列和执行方法等基础总结,目录如下: [TOC] GCD是什...

  • iOS GCD&&多线程

    iOS GCD&&多线程 基础篇 GCD用途 GCD 是 Grand Central Dispatch 的缩写。 ...

  • iOS 开发之 GCD 不同场景使用

    iOS 开发之 GCD 不同场景使用 本文在iOS 开发值 GCD 基础 的基础上,继续总结了 GCD 的一些AP...

  • iOS多线程之GCD - 基础

    GCD系列 GCD基础 GCD进阶函数 调度组dispatch_group 信号量dispatch_semapho...

  • 高级iOS面试题全纪录

    iOS基础: 多线程使用,gcd跟operation区别,怎么取消正在执行的gcd任务 GCD 系列知识总结 NS...

  • iOS GCD的使用

    什么是GCD了解GCD前,需要了解的基础知识GCD的使用使用注意事项 -GCD学习前铺垫-什么是GCDGCD (G...

  • iOS GCD的使用

    本文的主要内容是: 什么是GCD 了解GCD前,需要了解的基础知识 GCD的使用 使用注意事项 -GCD学习前铺垫...

  • iOS GCD (二 ) dispatch_group 队列组

    iOS GCD (一) 任务+队列 基础组合iOS GCD (二 ) dispatch_group 队列组iO...

  • iOS GCD(六)线程加锁

    iOS GCD (一) 任务+队列 基础组合iOS GCD (二 ) dispatch_group 队列组iO...

  • iOS GCD(五) 死锁案例分析

    iOS GCD (一) 任务+队列 基础组合iOS GCD (二 ) dispatch_group 队列组iO...

网友评论

      本文标题:GCD基础

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