摘自: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. java基础知识6-- 抽象类,抽象方法,接口,构造方法,类方法等易混淆的知识点

    一.抽象类和抽象方法 (B 继承  抽象类A) 抽象类:有抽象方法的一定是抽象类 抽象方法:方法名前有abstract修饰,且方法没有方法体,即{},不需要实现任何功能,只是声明 1.抽象类中的方法有 ...

  2. Eclipse中删除tomcat server 导致不能重新创建该版本的tomcat server

    在Eclipse中创建了一个Web工程后,需要将该工程部署到Tomcat中进行发布.有时就会遇到在New Server对话框中选择了Tomcat 6/7后却无法单击“Next”按钮的问题,如下图所示: ...

  3. 基于CSS UI开源框架汇总

    从16年数据统计就有20几款UI框架出现在市面上,至今为止能统计的框架应该有40款左右了.前端框架都是基于HMTL5.CSS.JS开发的,这里主要给大家聊一下CSS UI开源框架有哪些?以后工作中选择 ...

  4. (转)添加PROPAGATION_REQUIRES_NEW 事务没有产生作用

    最近在做事务添加时  发现自己的事务没有新建,上网查到   仅用作收藏. 其二  注意  事务的注解  应该在 内层的事务上面 一.描述 Spring遇到嵌套事务时,当被嵌套的事务被定义为" ...

  5. 利用ASP.NET操作IIS (可以制作安装程序)

    很多web安装程序都会在IIS里添加应用程序或者应用程序池,早期用ASP.NET操作IIS非常困难,不过,从7.0开始,微软提供了 Microsoft.Web.Administration 类,可以很 ...

  6. TCP/IP中你不得不知的十大秘密

    这段时间 有一点心很浮躁,不过希望自己马上要矫正过来.好好学习编程!这段时间我想好好地研究一下TCP/IP协议和网络传输这块!加油 一.TCP/IP模型 TCP/IP协议模型(Transmission ...

  7. 多线程进阶---Thread.join()/CountDownLatch.await() /CyclicBarrier.await()

    Thread.join() CountDownLatch.await() CyclicBarrier.await() 三者都是用来控制程序的"流动" 可以让程序"堵塞&q ...

  8. SSM框架—详细整合教程(Spring+SpringMVC+MyBatis)

    很久没有新搭建过框架了,今天搭建一遍.以往都是在eclipse中搭建,今天换Idea吧,目前来说Idea用的还是很多的,但是用习惯了eclipse的朋友,可能会不太习惯 ok.....开始: 注意区分 ...

  9. uvalive 7500 Boxes and Balls

    https://vjudge.net/problem/UVALive-7500 题意: 找到规律之后发现给出一个数n,要求找到1 + 2i + ... + x <= n,找出1到x的和. 思路: ...

  10. Linux入门之常用命令(7)压缩

    compress filename 压缩   -d解压缩  *.Z bzip -d解压缩 -z压缩 *.bz2 bzcat filename .bz2 读取压缩文件内容 gzip -d解压缩  -#压 ...