iOS:转载:同步、异步、并行、串行的详解
理解 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:转载:同步、异步、并行、串行的详解的更多相关文章
- iOS:GCD理解1(同步-异步、串行-并行)
1.并行-异步(ST1与ST2抢占资源) 1-1).获取 并行(全局)队列 ,DISPATCH_QUEUE_PRIORITY_DEFAULT 为默认优先级. dispatch_queue_t queu ...
- iOS GCD NSOperation NSThread等多线程各种举例详解
废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址
- 【原】iOS多线程之异步任务+并行队列情况与异步任务+串行队列(主队列)情况
异步任务+并行队列 把异步任务放到并行队列进行执行,异步任务会在不同的线程中执行. /*异步执行+并行队列*/ - (IBAction)clickBasic1:(UIButton *)sender { ...
- VLC命令行参数详解
VLC命令行参数详解 2012-11-29 14:00 6859人阅读 评论(0) 收藏 举报 Usage: vlc [options] [stream] ...You can specify mul ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- 转:MySQL Row Format(MySQL行格式详解)
MySQL Row Format(MySQL行格式详解) --转载自登博的博客
- 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)
李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...
- appledoc导出iOS代码文档的使用和问题详解(干货篇)
appledoc导出iOS代码文档的使用和问题详解(干货篇) 1. 简单说一下背景和自己感受 背景: 项目好像突然黄了,公司让详细写项目代码的注释并且导出文档,弄完之后就要封版. 说实话:听到这个消息 ...
- iOS GCD, 同步,异步,串行队列,并行队列,dispatch_group
同步,指代码在同一个线程运行 异步,代码在另一个线程运行 串行队列,提交到该队列的block会顺序执行 并行队列,提交到该队列的block会并发执行 如果想等某一队列中所有block都执行完了在执行一 ...
随机推荐
- Linux非常用命令
查看系统版本(64位还是32位版本) uname -a 或 more /proc/version 执行结果
- Mysql优化之my.cnf参数优化
1.innodb_buffer_pool_size innodb_buffer_pool_size 参数用来设置Innodb 最主要的Buffer(Innodb_Buffer_Pool)的大小,也就是 ...
- 安卓屏幕旋转时,禁止Activity重新加载
安卓设备旋转屏幕时,Activity默认会重新加载,如果是要读取大量数据的场景,那等待的时间比较长,这一点不可接受,所以要想办法禁止Activity自动重新加载. 方法如下在AndroidManife ...
- Java字符串易错方法总结
Java字符串易错方法总结 public String[] split(String regex) 和 public String[] split(String regex,int limit) li ...
- 解析 Qt 程序在Windows 下发布
原文请看:http://www.cnblogs.com/elect-fans/archive/2012/03/15/2408579.html Qt 程序在Windows下发布是本文要介绍的内容,不多说 ...
- 嵌套循环连接(Nested Loops Joins)
The nested loops join, also called nested iteration, uses one join input as the outer input table(sh ...
- 《深入理解Android2》读书笔记(七)
接上篇<深入理解Android2>读书笔记(六) 广播接受者 注册 ContextImpl @Override public Intent registerReceiver(Broadca ...
- 异步加载 Echarts图的数据
<script src="~/Scripts/NewEcharts/echarts.js"></script> <script type=" ...
- 有一种感动叫ACM(WJMZBMR在成都赛区开幕式上的讲话)
各位选手,各位教练,大家好,我是来自清华大学交叉信息学院的陈立杰,今天很荣幸站在这里代表全体参赛选手发言.对于我来说,这是我第一次正式参加ACM的比赛.不过我跟ACM之间的缘分,大概在很早的时候就已经 ...
- STM32通用定时器实现LED灯闪烁
刚才看了一下STM32通用定时器的教程,其实和51的定时器使用差不多.只是因为32的时钟更复杂,可操控的寄存器更多,所以写的时候可能更复杂. 使用通用定时器中断的一般步骤:1.使能定时器时钟 这个需要 ...