zoukankan      html  css  js  c++  java
  • GCD简介

    1、GCD简介

    • GCD 是 Grand Central Dispatch(译为 “中枢调度器”)的简称,它是基于 C 语言编写的,是苹果公司为多核的并行运算提出的解决方案。

    • GCD 在工作时会自动利用更多的处理器核心,以充分利用更强大的机器。

    • 如果使用 GCD,完全由系统管理线程,我们不需要编写线程代码,只需定义想要执行的任务,然后添加到适当的调度队列(dispatch queue),GCD 会负责创建线程和调度你的任务。

    • 它首次发布在 Mac OS X 10.6 ,iOS 4 上。在 iOS 所有实现多线程的方案中,GCD 应该是最有魅力的,GCD 是一个替代诸如 NSThread, NSOperationQueue,NSInvocationOperation 等技术的很高效和强大的技术。

    • 1.1 工作原理:

      • 将长期运行的任务拆分成多个工作单元,并将这些单元添加到 dispath queue 中,系统会为我们管理这些 dispath queue,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
      • 我们不需要直接启动和管理后台线程。
      • 一个任务可以是一个函数(function)或者是一个 block。
      • GCD 的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
      • 将任务添加到队列,并且指定执行任务的函数,执行任务。任务使用 block 封装,任务的 block 没有参数也没有返回值。
    • 1.2 执行任务的函数:

      • 异步 dispatch_async
        • 不用等待当前语句执行完毕,就可以执行下一条语句。
        • 会开启线程执行 block 的任务。
        • 异步是多线程的代名词。
      • 同步 dispatch_sync
        • 必须等待当前语句执行完毕,才会执行下一条语句。
        • 不会开启线程。
        • 在当前线程执行 block 的任务。
        • 同步任务的作用:同步任务,可以让其他异步执行的任务,"依赖" 某一个同步任务。例如:在用户登录之后,再异步下载文件!
    • 1.3 任务调度队列:

      • GCD 中的 FIFO 队列称为 dispatch queue(调度队列)。系统提供了许多预定义的 dispatch queue,包括可以保证始终在主线程上执行工作的 dispatch queue。
      • 也可以创建自己的 dispatch queue,而且可以创建任意多个。GCD 的 dispatch queue 严格遵循 FIFO(先进先出) 原则,添加到 dispatch queue 的工作单元将始终按照加入 dispatch queue 的顺序启动。
      • dispatch queue 按先进先出的顺序,串行或并发地调度任务在线程上实行。
      • dispatch queue 分为下面三种:
        • Serial:

          • 串行队列,又称为 private dispatch queues,一次只能 "调度" 一个任务, 当前任务完成才开始出列并启动下一个任务。Serial queue 通常用于同步访问特定的资源或数据。当你创建多个 Serial queue 时,虽然它们各自是同步执行的,但 Serial queue 与 Serial queue 之间是并发执行的。
        • Concurrent:

          • 并发队列,又称为 global dispatch queues,一次可以 "调度" 多个任务,尽可能多地启动任务并发执行,任务执行完成的顺序是随机的。
          • 系统给每一个应用程序提供了三个 concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数 dispath_get_global_queue 去得到队列。
        • Main dispatch queue:

          • 主队列,它是全局可用的 serial queue,专门用来在主线程上调度任务的队列。不会开启线程,主队列异步执行时如果主线程上正在有代码执行,就不会调度队列中的任务,等待主线程空闲之后再调度任务。主线程中主队列同步执行时,主队列和主线程相互等待会造成死锁。
    • 1.4 各种队列的执行效果:

      Type 全局并发队列 手动创建串行队列 主队列
      同步 (sync) 没有开启新线程 没有开启新线程 没有开启新线程
      ~ 串行执行任务 串行执行任务 串行执行任务
      异步 (async) 有开启新线程 有开启新线程 没有开启新线程
      ~ 并发执行任务 串行执行任务 串行执行任务
      • 开不开线程由执行任务的函数决定:
        • 异步开,异步是多线程的代名词。
        • 同步不开。
      • 开几条线程由队列决定:
        • 串行队列开一条线程。
        • 并发队列开多条线程。
        • 主队列不会开启线程。
    • 1.5 队列的选择:

      • 多线程的目的:将耗时的操作放在后台执行!
      • 串行队列,只开一条线程,所有任务顺序执行
      • 如果任务有先后执行顺序的要求。
        • 效率低 -> 执行慢 -> "省电"。
      • 有的时候,用户其实不希望太快!例如使用 3G 流量,"省钱"。
      • 并发队列,会开启多条线程,所有任务不按照顺序执行
      • 如果任务没有先后执行顺序的要求。
        • 效率高 -> 执行快 -> "费电"。
      • WIFI,包月。
      • 实际开发中
      • WIFI 线程数 6 条。
      • 3G / 4G 移动开发的时候,2~3 条,再多会费电费钱。
    • 1.6 全局队列 & 并发队列的区别:

      • 1)全局队列:

        • 没有名称。
        • 无论 MRC & ARC 都不需要考虑释放。
        • 日常开发中,建议使用 "全局队列"。
      • 2)并发队列:

        • 有名字,和 NSThread 的 name 属性作用类似。
        • 如果在 MRC 开发时,需要使用 dispatch_release(q); 释放相应的对象。
        • 开发第三方框架时,建议使用并发队列。
    • 1.7 GCD & NSThread 对比:

      • GCD 所有的代码写在一起的,让代码更加简单,易于阅读和维护。
      • NSThread 通过 @selector 指定要执行的方法,代码分散。
      • GCD 通过 block 指定要执行的代码,代码集中。
      • 使用 GCD 不需要管理线程的创建/销毁/复用的过程。程序员不用关心线程的生命周期。
      • NSThread 需要自己创建线程对象,并且指定 selector 方法,然后 start。
      • GCD 只需要将任务添加给队列,并且指定执行的函数
      • 如果要开多个线程 NSThread 必须实例化多个线程对象。
      • NSThread 靠 NSObject 的分类方法实现的线程间通讯,GCD 靠 block。
  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/CH520/p/12826323.html
Copyright © 2011-2022 走看看