理解 iOS 开发中 GCD 相关的同步(synchronization)\ 异步(asynchronization),串行(serial)\ 并行(concurrency)概念

iOS 开发过程中,常常需要用到多线程技术,GCD 是常用的实现多线程的技术,其因简洁底层而备受欢迎。

GCD 技术中,同步(synchronization)\ 异步(asynchronization),串行(serial)\ 并行(concurrency)等概念常常令人迷惑,不好理解。本文将对这两对概念进行尽可能简单的阐释。

同步和异步是针对当前代码流(即当前线程)和加入队列中的任务之间执行顺序的关系而言的。以同步的方式向队列中添加任务会阻塞当前线程,直到同步到队列中的任务执行完毕返回后,才会接着执行当前的代码流;以异步的方式向队列中添加的任务则不会阻塞当前线程,将任务添加到队列中后,不用等待任务执行完毕,即刻执行当前代码流。举例说明如下:


同步(dispatch_sync):

    dispatch_sync(myQueue,^{
printf("1"); //任务 1
});
printf("2");
dispatch_sync(myQueue,^{
printf("3"); //任务 3
});
printf("4");

上面的代码执行结果只有一种可能,即输出“1234”。

在将输出 1 的任务(即代码中任务 1)同步到队列 myQueue 中后,当前线程阻塞,等待任务 1 执行完毕并返回后(即输出 1 之后),才能接着执行当前线程,输出 2。输出 2 之后,当前代码流继续运行,将任务 3 再同步到队列 myQueue 中后,当前线程阻塞,等待任务 3 执行,输出 3,之后当前代码流继续运行输出 4。

这段代码的输出结果与 myQueue 是串行队列还是并行队列没有关系。


异步(dispatch_async):

    dispatch_async(serialQueue,^{
printf("1"); //任务 1
});
printf("2");
dispatch_async(serialQueue,^{
printf("3"); //任务 3
});
printf("4");

上面代码执行结果可能为 “1234”、“1243”、“2134”、“2143”、“2413” 中的一种,2 始终在 4 前面,1 始终在 3 前面(注意:此例中的队列(serialQueue)为串行队列,串行队列的概念将在后文讲述),2 始终在 3 前面。

将任务 1 异步添加到队列 serialQueue 中之后,不需要等待其执行完毕,当前代码流就继续执行了。当前代码流输出 2 时,可能任务 1 还没执行,也可能执行完毕了,因此 1 可能在 2 前输出也可能在 2 后输出;

同理,将任务 3 异步添加到队列 serialQueue 中之后,不需要等待其执行完毕,当前代码流就继续执行。当前代码流输出 4 时,可能任务 3 还没执行,也可能执行完毕了,因此 3 可能在 4 前输出也可能在 4 后输出。

对于当前代码流,输出 2 一定在 输出 4 前执行,因此 2 必定在 4 前输出。

对于串行队列 serialQueue ,任务 1 一定在 任务 3 前执行,因此 1 必定在 3 前输出。

将任务 3 添加到队列 serialQueue 的操作必定在输出 2 后进行,因此 2 必定在 3 前输出。


串行和并行是针对一个队列中的多个任务执行顺序而言的。串行队列是指队列中的任务是一个接一个地执行的,队首的任务执行完毕后才能执行其后面的任务,直至执行队尾的任务;并行队列是指队列中的任务可以并发地执行,即开始执行队首的任务后,不必等其执行完毕就可以接着开始执行队首之后的任务,因此在某一时刻可能存在同时执行的多个任务。

创建串行队列的方法是:

 dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", NULL); 

 dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL);

同时主线程的队列也是串行队列,获取方法:

dispatch_queue_t mainQueue = dispatch_get_main_queue();

创建并行队列的方法是:

dispatch_queue_t concurrentQueue = dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);

同时系统提供了获取系统并发队列的函数:

dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);

第一个参数 identifier 的值宏定义可以为

DISPATCH_QUEUE_PRIORITY_HIGH、

DISPATCH_QUEUE_PRIORITY_DEFAULT、

DISPATCH_QUEUE_PRIORITY_LOW、

DISPATCH_QUEUE_PRIORITY_BACKGROUND,

四个参数值获取的并发队列优先级依次从高到低;第二个参数 flags为系统保留参数,应传入值 0。


混淆同步异步和并行串行的概念,是因为我们没有弄清楚它们分别针对的对象是什么,一旦明白了它们描述的对象的区别,就不会在混淆了。再次总结一下,同步异步描述的是当前线程或代码流是否要阻塞以等待加入队列的任务执行完毕:同步要阻塞当前线程;异步不会阻塞当前线程。串行和并行描述的时队列里各个任务是否可以并发执行:串行队列里的任务不能并发执行,只能一个接一个地执行,同一时刻该串行队列里的任务最多只有一个在执行;并发队列里的任务后面的任务不必等待前面的任务执行完毕再执行,可以多个同时执行,同一时刻该并行队列里的任务可以有多个正在执行。

iOS:转载:同步、异步、并行、串行的详解的更多相关文章

  1. iOS:GCD理解1(同步-异步、串行-并行)

    1.并行-异步(ST1与ST2抢占资源) 1-1).获取 并行(全局)队列 ,DISPATCH_QUEUE_PRIORITY_DEFAULT 为默认优先级. dispatch_queue_t queu ...

  2. iOS GCD NSOperation NSThread等多线程各种举例详解

    废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址

  3. 【原】iOS多线程之异步任务+并行队列情况与异步任务+串行队列(主队列)情况

    异步任务+并行队列 把异步任务放到并行队列进行执行,异步任务会在不同的线程中执行. /*异步执行+并行队列*/ - (IBAction)clickBasic1:(UIButton *)sender { ...

  4. VLC命令行参数详解

    VLC命令行参数详解 2012-11-29 14:00 6859人阅读 评论(0) 收藏 举报 Usage: vlc [options] [stream] ...You can specify mul ...

  5. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  6. 转:MySQL Row Format(MySQL行格式详解)

    MySQL Row Format(MySQL行格式详解) --转载自登博的博客

  7. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  8. appledoc导出iOS代码文档的使用和问题详解(干货篇)

    appledoc导出iOS代码文档的使用和问题详解(干货篇) 1. 简单说一下背景和自己感受 背景: 项目好像突然黄了,公司让详细写项目代码的注释并且导出文档,弄完之后就要封版. 说实话:听到这个消息 ...

  9. iOS GCD, 同步,异步,串行队列,并行队列,dispatch_group

    同步,指代码在同一个线程运行 异步,代码在另一个线程运行 串行队列,提交到该队列的block会顺序执行 并行队列,提交到该队列的block会并发执行 如果想等某一队列中所有block都执行完了在执行一 ...

随机推荐

  1. linux删除乱码文件[转载]

    一些乱码文件不可以通过普通的rm命令进行管理.可以通过删除i节点的方式删除. [root@192_168_100_35 musicwap]# ls??,?K?k?ͨa*.?J]?k?Φ??P???Z? ...

  2. 听justjavac大神live前端的入门与进阶小笔记

    代码规范 代码强壮,调试代码 少用变量,多用常量 少用for循环,why循环,多用函数式, 不要直接去使用框架 刷题 提高编程思维 用js去做c语音的问题 阅读别人代码,去看别人的代码 a+b> ...

  3. Python基础系列----环境的搭建及简单输入、输出

    1.Python                                                                                         以下信 ...

  4. electron 编译 sqlite3避坑指南---尾部链接有已经编译成功的sqlite3

    electron 编译 sqlite3避坑指南(尾部链接有已经编译成功的sqlite3) sqlite很好用,不需要安装,使用electron开发桌面程序,sqlite自然是存储数据的不二之选,奈何编 ...

  5. 前端组件化-Web Components【转】

    以下全部转自:http://www.cnblogs.com/pqjwyn/p/7401918.html 前端组件化的痛点在前端组件化横行的今天,确实极大的提升了开发效率.不过有一个问题不得不被重视,拟 ...

  6. requere.js优化js脚本加载方案,使用篇。

    require.config({ paths: { "jquery": "jquery-3.2.1", 'index':"index" }} ...

  7. ajax向php传参数对数据库操作

    刚入门php,要求要对多用户进行批量删除(当然实际中是不可能的),在这就以此为例. 大意就是通过对数据库中用户查询,将用户信息显示在页面表格中,在进行多项选择后将所选行参数通过ajax传入后台php文 ...

  8. ZOJ 2974 Just Pour the Water

    矩阵快速幂. 构造一个矩阵,$a[i][j]$表示一次操作后,$j$会从$i$那里得到水的比例.注意$k=0$的时候,要将$a[i][j]$置为$1$. #pragma comment(linker, ...

  9. 决策树:ID3与C4.5算法

    1.基本概念 1)定义: 决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系,树中每个节点代表的某个可能的属性值. 2)表示方法: 通过把实例从根结点排列到某个叶子结点来分类实例,叶子 ...

  10. 读书笔记(高性能javascript)(二)

    5. 字符串和正则表达式: (1) 在大多数浏览器中,数组项合并(Array.prototype.join)比其他字符串连接方法更慢,但它却在IE7及更早版本浏览器中合并大量字符串唯一高效的途径: ( ...