大中央派遣-如何终端! (快速3)

嗯,多线程,并发等等。 这些都是在Flatiron学校的话题,我们被告知“这确实很重要”,现在我开始寻找工作,阅读工作说明并进行技术面试,现在我意识到Flatiron并不是在撒谎。

因此,在这里,我们只关注一件事: 中央中央调度(GCD)

Grand Central Dispatch(以前称为libdispatch的框架是Apple的框架,用于将并发(管理同时发生的多件事)合并到您的应用程序中。 基本上,GCD会为我们管理队列(为我们完成所有任务调度!),因此我们不必考虑如何合并线程或在哪里“锁定”代码行。 GCD允许我们(开发人员)考虑将代码编写为单个线程或进程,因此,我们只需要考虑在哪里分解我们的部分代码以在另一个线程上运行。

Apple文档指出,“ GCD提供并管理FIFO(先进先出)队列,您的应用程序可以以块对象的形式向其提交任务。 提交给调度队列的工作在系统完全管理的线程池上执行。 无法保证执行任务的线程。”

简而言之,GCD是我们的小帮手,因为它:

  • 因为它在后台运行长时间运行的任务,所以有助于提高我们的应用性能。
  • 通过避免在新线程上设置锁和分离代码的需要,使开发人员更轻松(如果操作不正确,可能会导致并发错误)
  • 可以提高代码性能,例如单例。

因此,让我们退后一步,回顾一些在开始讨论GCD之前需要理解的词汇和概念:

  • 任务=需要完成的一项工作(即API调用)。
  • 线程=操作系统提供的进程,它允许多个指令集(又称代码行)在单个应用程序中同时运行。
  • 进程=代码的可执行部分,可能在多个线程中。

太酷了,既然我们已经把这些术语简化了,让我们来谈谈任务的执行方式。

串行调度队列与并发调度队列

如果一项任务一次执行一次,则称它是串行执行的 如果可以同时执行多个任务,则称它们是同时执行的。

Grand Central Dispatch提供了调度队列(以“队列”为一行),使您可以在所谓的并发调度队列上并发运行代码块。 使用并发调度队列,我们​​有多个线程可用于同时处理多个代码块。 这种队列不同于串行调度队列串行调度队列一次只在一个线程上添加一件工作。

同步与异步执行

函数可以是同步的也可以是异步的。 同步功能仅在上一个任务完成后返回 。 我喜欢将其视为“同步”(有趣的事实:NSYNC是我一直以来最喜欢的男孩乐队)。 异步意味着它可以立即运行,而无需等待上一个任务完成就可以开始。 因此,它不是同步的(我喜欢将异步看作是我的NSYNC的后街男孩)。

大中央调度:我们如何使用它?

如前所述,GCD为我们提供了调度队列,用于管理代码块。 这些分派队列负责处理我们提供给GCD的任务,并按FIFO先进先出 )顺序进行处理(第一个任务排在队列的首位,依此类推)。

您还记得在串行调度队列中 ,一次只执行一个代码块。 在GCD中,这些块的执行时间在GCD的控制之下。 换句话说,我不知道代码的第1、2和3块要花多长时间,但是我知道两件事:1)每个块一次要运行一个,2)他们要运行一次以添加它们的顺序运行。

对于并发调度队列,可以同时执行多个代码块。 GCD的工作是决定何时启动每个块。 由于这些是同时运行的多个代码块,并且将重复执行这些代码块,因此GCD 决定何时这些块之一应在其他内核上运行 (一个内核是计算机的处理器之一。我的Macbook Pro笔记本电脑具有两个,因此是双核。考虑2个核= 2个线程!)。 GCD会确定内核(线程)是否可用,并且可以在这些可用线程上打开和关闭代码块,以使您的代码高效运行。 因此,如果您在想:“等等,我不必弄清楚要在哪个线程上放置此代码,那么GCD将为我高效地做到这一点?”您是正确的。

队列类型

还要注意的另一件事是GCD为我们管理的队列的不同类型。 在谈论GCD时,了解队列的类型很重要。

默认情况下,我们执行的所有操作都在“主线程”或“主队列”上。此“主”队列是一个串行队列(一次运行一个,又名同步运行)。 重要的是要了解,主队列会处理屏幕上绘制的所有内容(UI视图),响应鼠标事件,触摸事件和键盘事件。

就并发队列(也称为全局调度队列)而言,它们自己的服务质量类中有四个选项:用户交互,用户启动,实用程序和背景。 (您还可以创建自己的自定义队列(串行或并发队列),但这是另一篇博客文章🙂

QOS_CLASS_USER_INTERACTIVE =使用此并发队列处理需要立即完成的任务(UI更新,处理事件)。 您应该最少使用此队列。

QOS_CLASS_USER_INITIATED =使用此并发队列执行用户从UI启动的任务。 如果用户希望他们的操作做出响应(点击按钮等),则应使用此选项。

QOS_CLASS_UTILITY =将此并发队列用于长时间运行的任务(即网络,计算)。 您应该将其与活动(进度)指示器一起使用,以便用户知道他们正在等待。

QOS_CLASS_BACKGROUND =使用此并发队列处理可能在后台执行的任务(又名用户不需要了解这些任务)。 您应该将其用于不真正涉及用户交互且不立即需要的任务。

如果我要强制GCD将某些内容放入“主队列”怎么办?

好问题。 好吧,您可以简单地告诉GCD以异步方式将代码块放在主体上:

为此,只需获取代码块(在上面的示例中为完成处理程序),然后调用DispatchQueue.main.async {}。

并发,NSOperation,多线程和GCD领域还有很多,但这是对Grand Central Dispatch的作用以及如何强制GCD在主线程上进行操作的简要概述。

享受排队您的代码!

资源:

GCD — Apple文档

大中央调度教程— Ray Wenderlich