摘自:http://www.cocoachina.com/swift/20150129/11057.html

libdispatch是Apple所提供的在IOS和OS X上进行并发编程的库,而GCD正是它市场化的名字。GCD有如下优点: – GCD可以将计算复杂的任务放到后台执行,从而提升app的响应性能 – GCD提供了比锁和线程更简单的并发模型,帮助开发者避免并发的bug。

为了理解GCD,你需要了解一些线程和并发的概念。这些概念可能很含糊并且细微,所以先简要回顾一下。

串行 vs 并发

这两个词用来描述任务的执行顺序。串行在同一时间点总是单独执行一个任务,而并发可以同时执行多个任务。

任务

在本教程中,你可以把任务当做一个闭包(closure)。实际上,你可以将GCD和函数指针一起使用,但是一般很少这样使用。闭包更简单!

不记得Swift中的闭包?闭包是自含的,可保存传递并被调用的代码块。当调用的时候,他们的用法很像函数,可以有参数和返回值。除此之外,闭包可以“捕获”外部的变量,也就是说,它可以看到并记住它自身被定义时的作用域变量。

Swift中的闭包和OC中的块(block)类似甚至于他们几乎就是可交换使用的。唯一的限制在于OC中不能使用Swift独有的特性,比如元组(tuple)。但OC中的块可以安全的替换成Swift中的闭包。

同步 vs 异步

这两个词描述的是函数何时将控制权返回给调用者,以及在返回时任务的完成情况。

同步函数只有在任务完成后才会返回。

异步函数会立即返回,不会等待任务完成。因此异步函数不会阻塞当前线程。

注意:当你读到同步函数阻塞(block)当前进程或者函数是阻塞(blocking)函数时,不要困惑!动词阻塞(block)描述的是函数对当前线程的影响,和块(block)没有关系。同时记住GCD文档中有关OC的block可以跟Swift的闭包互换。

临界区(Critical Section)

这是一段不能并发执行的代码,也就是说两个线程不可以同时执行它。这通常是因为这段代码会修改共享的资源。否则,并发的进程同时修改同一个变量会导致错误。

竞态条件

当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。竞态条件可能产生在代码检查时不易被发现的不可预期行为。

死锁

两个或更多的线程因等待彼此完成而陷入的困境称为死锁。第一个线程无法完成因为它在等待第二个线程完成。但是第二个线程也无法完成因为它在等待第一个线程完成。

线程安全

线程安全的代码是可以被多个线程或并发任务安全调用的,他不会造成任何问题(数据错误, 崩溃等)。非线程安全的代码在同一时间只能单独执行。一段线程安全的代码如let a = ["thread-safe"]。由于数组是只读的,它可以被多个线程同时使用而不会引发问题。另一方面,var a = ["thread-unsafe"]是可变数组。这意味着它不是线程安全的,因为多个线程可以同时获取并修改这个数组,会得到不可预料的结果。非线程安全 的变量和可变的数据结构在同一时刻应该只能被一个线程获取。

上下文切换

上下文切换是在进程中切换不同线程时保存和恢复程序执行状态的过程。这一过程在编写多任务app时相当常见,但是会造成一些额外开支。

并发 vs 并行

并发和并行经常会被同时提起,所以值得通过简短的解释来区分彼此。

并发代码中的单独部分可以同时执行。然而,这要由系统来决定并发怎样发生或是否发生。

多核设备通过并行来同时执行多个线程;然而,在单核设备中,必须要通过上下文切换来运行另一个线程或进程。这一过程通常发生的很快以至于给人并行的假象。

队列

GCD提供了调度队列(dispatch queues)来处理提交的任务;这些队列管理着你向GCD提交的任务并且以先进先出(FIFO)的顺序来执行任务。这保证了第一个加入队列的任务第一个被执行,第二个加入的任务第二个开始执行,以此类推。

所有调度队列都是线程安全的从而让你可以同时在多个线程中使用它们。当你明白了调度队列如何为你的代码提供了线程安全性时,GCD的优点就很明显了。关键是选择正确的调度队列种类和正确的调度函数(dispatching function)来提交你的任务。

顺序队列

顺序队列中的任务同一时间只执行一件任务,每件任务只有在先前的任务完成后才开始。同时,你并不知道一个任务完成到另一个任务开始之间的间隔时间

任务的执行是在GCD掌控之下的;你唯一确定的就是GCD在同一时刻只执行一件任务并且按任务加入队列的顺序执行。

因为不会在顺序队列中同时执行两件任务,所以没有多个任务同时进入临界区的危险;这保证了临界区不会出现竞态条件。因此如果进入临界区的唯一途径就是通过向调度队列提交任务,那么可以保证临界区是安全的。

并发队列中的任务可以保证按进入队列的顺序被执行…仅此而已!任务可能以任意顺序完成而且你不知道何时下一个任务会开始,或是任一时刻有多少任务在运行。再一次,这完全取决于GCD。 下图展示了四个并发任务的例子:

何时开始一个任务完全取决于GCD。如果一个任务的执行时间和另一个的发生重叠,将由GCD来决定是否要将任务运行在另一个可用的核上或是通过上下文切换来运行另一个程序。

首先,系统提供了一种特殊的顺序队列main queue。和其他的顺序队列一样,在这个队列里的任务同一时刻只有一个在执行。然而,这个队列保证了所有任务会在主线程中执行,主线程是唯一一个允许更新UI的线程。这个队列用来向UIView对象发消息或发通知。

系统同时提供了几种并发队列。这些队列和它们自身的QoS等级相关。QoS等级表示了提交任务的意图,使得GCD可以决定如何制定优先级。

  • QOS_CLASS_USER_INTERACTIVE: user interactive等级表示任务需要被立即执行以提供好的用户体验。使用它来更新UI,响应事件以及需要低延时的小工作量任务。这个等级的工作总量应该保持较小规模。

  • QOS_CLASS_USER_INITIATED:user initiated等级表示任务由UI发起并且可以异步执行。它应该用在用户需要即时的结果同时又要求可以继续交互的任务。

  • QOS_CLASS_UTILITY:utility等级表示需要长时间运行的任务,常常伴随有用户可见的进度指示器。使用它来做计算,I/O,网络,持续的数据填充等任务。这个等级被设计成节能的。

  • QOS_CLASS_BACKGROUND:background等级表示那些用户不会察觉的任务。使用它来执行预加载,维护或是其它不需用户交互和对时间不敏感的任务。

ios 中的 GCD的更多相关文章

  1. 玩转iOS开发:iOS中的GCD开发(三)

    上一章, 我们了解到了GCD里的一些队列和任务的知识, 也实践了一下, 同时我们也对主队列的一些小情况了解了一下, 比如上一章讲到的卡线程的问题, 如果没有看的朋友可以去看看玩转iOS开发:iOS中的 ...

  2. iOS中的GCD线程

    一.什么是GCD      全称是Grand Central Dispatch ,纯C语言编写,提供非常多强大的函数,是目前苹果官网推荐的多线程开发方法,NSOperation 便是基于GCD的封装 ...

  3. ios中多线程GCD NSOperation NSThread 相关的操作解析

    //1.GCD 继承自C语言 优点 简单方便 //开启一个子线程处理耗时的操作 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIO ...

  4. IOS中的多线程之GCD

    在ios中,使用多线程有三种方式,分别是:NSThread.NSOperation和NSOperationQueue.GCD,在本节,主要讲解一下CDD的使用. GCD(Grand Central D ...

  5. iOS中GCD的使用小结

    http://www.jianshu.com/p/ae786a4cf3b1 本篇博客共分以下几个模块来介绍GCD的相关内容: 多线程相关概念 多线程编程技术的优缺点比较? GCD中的三种队列类型 Th ...

  6. iOS中的几种锁的总结,三种开启多线程的方式(GCD、NSOperation、NSThread)

    学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary OC中的几种锁 为什么要引入锁 ...

  7. iOS中多线程知识总结(一)

    这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序.   ...

  8. 谈谈iOS中的锁

    1 前言 近日工作不是太忙,刚好有时间了解一些其他东西,本来打算今天上午去体检,但是看看天气还是明天再去吧,也有很大一个原因:就是周六没有预约上!闲话少说,这里简单对锁来个简单介绍分享. 2 目录 第 ...

  9. ios线程和GCD

    1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一 ...

随机推荐

  1. JDBC在javaweb中的应用之分页数据查询

    分页查询 分页查询是java web开发中经常使用到的技术.在数据库中数据量非常大的情况下,不适合将所有的数据全部显示到一个页面中,同时为了节约程序以及数据库的资源,就需要对数据进行分页查询操作. 通 ...

  2. JDBC操作数据库之批处理

    JDBC开发中,操作数据库需要和数据库建立连接,然后将要执行的SQL语句发送到数据库服务器,最后关闭数据库连接,都是按照这样的操做的,如果按照此流程要执行多条SQL语句,那么就要建立多个数据库连接,将 ...

  3. 自定义Django的中间件

    分析Django的生命周期,我们知道所有的http请求都要经过Django的中间件. 假如现在有一个需求,所有到达服务端的url请求都在系统中记录一条日志,该怎么做呢? Django的中间件的简介 D ...

  4. Matlab入门学习(矩阵、函数、绘图的基本使用)

    一.矩阵 1.定义和简单使用(一般的编程语言,数组下标都是从0开始的,但是MATLAB是从1开始的) >> a=[ ; ; ] a = >> b=[ ; ; ]; >&g ...

  5. datepickerpopup时间限制选取

    使用popup组件的过程中遇到时间选取的问题 官方文档大致说使用date和mode 可以解决,奈何老夫是看不懂,写的时候参考的有 官方文档.echo2016的博文.liumang361的博文 先看图 ...

  6. 我的python学习笔记一

    我的python学习笔记,快速了解python,适合有C语言基础的. http://note.youdao.com/noteshare?id=93b9750a8950c6303467cf33cb1ba ...

  7. 工欲善其事,必先利其器之open live writer写作

    在博客园学习有一段时间,想想是不是自己也应该开始写点东西,做点总结,更加快速的提升自己. 查看小组/博客园使用帮助 得知目前windows live writer 已经停止更新并推荐安装 open l ...

  8. mac 安装Beautiful Soup

    Beautiful Soup是一个Python的一个库,主要为一些短周期项目比如屏幕抓取而设计.有三个特性使得它非常强大: 1.Beautiful Soup提供了一些简单的方法和Python术语,用于 ...

  9. 第5章 不要让线程成为脱缰的野马(Keeping your Threads on Leash) ---线程优先权(Thread priority)

    有没有过这样的经验?你坐在你的车子里,目的地还在好几公里之遥,而时间已经很晚了.你拼命想告诉那些挡住你去路的人们,今天这个约会对你是多么多么重要,能不能请他们统统--呃--滚到马路外?很不幸,道路系统 ...

  10. 《Go in action》读后记录:Go的并发与并行

    本文的主要内容是: 了解goroutine,使用它来运行程序 了解Go是如何检测并修正竞争状态的(解决资源互斥访问的方式) 了解并使用通道chan来同步goroutine 一.使用goroutine来 ...