GCD中各种队列和任务执行方式的组合
一、概念回顾
1、GCD全称 Grand Central Dispatch ,是纯C语言,提供了非常多强大的函数,来进行系统线程的管理。
2、优势:GCD是苹果公司为多核的并行运算提出的解决方案。GCD会自动利用更多的CPU内核,会自动管理线程的生命周期(创建线程、调度任务、销毁线程),程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码。
3、GCD的两个核心:
(1)队列:GCD会从队列中取出任务,按照不同情况,放到对应的线程中执行,遵循FIFO原则。
队列共分有四种:
a、串行 :任务一个接一个的执行。
b、并发 :可以让任务同时执行,就是开启多个线程执行任务。
c、全局 :本质就是并发队列,区别:没有名称,不可跟踪;在MRC中释放次数不一样。
通过函数 dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)获得,第一个参数是优先级,第二个是预留(无用),一般二者都设为0。
d、主队列 :在主线程中顺序执行,有死锁现象(主队列同步执行的情况)。
(2)任务:就是要处理的事情。
任务处理(操作)方式有两种
a、同步 :在当前线程执行,不开辟新的线程。
b、异步 :在新的线程中执行任务,可以开启新的一条或多条线程。
4、队列和任务执行方式的组合
5、死锁描述:向串行队列里面分派同步任务(dispatch_sync)
二、实验观察线程管理情况
各种情况都写在viewDidLoad中,需要时打开注释,方便比较和查阅
- (void)viewDidLoad {
[super viewDidLoad]; //串行队列
dispatch_queue_t serial = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
//并行队列
dispatch_queue_t concurrent = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
//创建block1
dispatch_block_t block1 = ^{ //特意将第一个任务延迟一秒,用来观察执行顺序
[NSThread sleepForTimeInterval:];
NSLog(@" block1 ==> %@",[NSThread currentThread]);
};
//创建block2
dispatch_block_t block2 = ^{
NSLog(@" block2 ==> %@",[NSThread currentThread]);
}; #pragma mark - 串行同步 :在当前线程,FIFO顺序执行任务
// dispatch_sync(serial, block1);
// dispatch_sync(serial, block2); #pragma mark - 串行异步 :新建一个线程,出队列后按FIFO顺序执行
// dispatch_async(serial, block1);
// dispatch_async(serial, block2); #pragma mark - 并发同步 :在当前线程,出队列后顺序执行
// dispatch_sync(concurrent, block1);
// dispatch_sync(concurrent, block2); #pragma mark - 并发异步 :创建N个新线程,出队列后随机(同时)执行
// dispatch_async(concurrent, block1);
// dispatch_async(concurrent, block2); #pragma mark - 全局同步 :类似并发同步,全局队列是通过函数获得的
// dispatch_sync(dispatch_get_global_queue(0, 0), block1);
// dispatch_sync(dispatch_get_global_queue(0, 0), block2); #pragma mark - 全局异步 :类似并发异步
// dispatch_async(dispatch_get_global_queue(0, 0), block1);
// dispatch_async(dispatch_get_global_queue(0, 0), block2); #pragma mark - 主队列同步(死锁):主线程等待主队列中任务执行完毕(一直挂起,不是空闲)后面的代码都无法运行,然而主队列中的任务又在等待主线程空闲(也一直挂起,等待着主线程可以闲下来),所有两者相互等待,形成死锁。
// dispatch_sync(dispatch_get_main_queue(), block1);
// dispatch_sync(dispatch_get_main_queue(), block2); #pragma mark - 主队列同步(解死锁):加上一个全局异步,这样主线程不会卡住,主线程可以执行完它的代码,回过头来(此时空闲了),处理主队列里面的任务,不会锁死。
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
// NSLog(@"我是解锁的开始,此时线程 ===》%@ ",[NSThread currentThread]);
// dispatch_sync(dispatch_get_main_queue(), block1);
// dispatch_sync(dispatch_get_main_queue(), block2);
// NSLog(@"死锁被解开了!!%@ ",[NSThread currentThread]);
// }); #pragma mark - 主队列异步 : 主线程空闲时才执行主队列中的内容,出队列顺序执行 // dispatch_async(dispatch_get_main_queue(), block1);
// dispatch_async(dispatch_get_main_queue(), block2); NSLog(@" (主线程)我是写在程序最后的 =====》 end");
}
贴上几种组合的执行结果图(不是所有)
1、串行异步
2、并发同步
3、主队列同步 (解开死锁的情况)
4、主队列异步
三、总结
GCD管理线程,功能强大:有没有新线程看是否同步——异步;有没有顺序执行看是否串行——并行。
还有多种线程管理的方式:pthread、NSThread、NSOperation(NSInvocationOperation、NSBlockOperation),各有优缺点,以及使用的场景,以后再做讨论。
GCD中各种队列和任务执行方式的组合的更多相关文章
- iOS 关于GCD中的队列
GCD中队列分类及获得方式 1.串行队列 dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...
- 关于OC中的几种延迟执行方式
第一种: [UIView animateWithDuration: delay: options: animations:^{ self.btn.transform = CGAffineTransfo ...
- 读书笔记——spring cloud 中 HystrixCommand的四种执行方式简述
读了<Spring Cloud 微服务实战>第151-154页, 总结如下: Hystrix存在两种Command,一种是HystrixCommand,另一种是HystrixObserva ...
- shell中sparksql语句调试、执行方式
1.命令方式执行sparksql查询 SQL="use mydatatable;;select count(1) from tab_videousr_onlne where p_regiio ...
- iOS多线程中,队列和执行的排列组合结果分析
本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...
- IOS中延时执行方式
本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...
- Lua中实现队列(高效方式)
转自http://www.cnblogs.com/stephen-liu74/archive/2012/06/25/2417894.html 在Lua中实现队列的简单方法是使用table库函数inse ...
- Delphi中ADO异步执行方式
当ADO开始处理数据后,应用程序必须等到ADO处理完毕之后才可以继续执行.但是除了同步执行方式之外,ADO也提供了异步执行的方式,允许当ADO处理时,应用程序仍然能够先继续执行.而当ADO处理数据完毕 ...
- shell基础概念, if+命令, shell中引用python, shell脚本的几种执行方式
说明: 虚拟机中shell_test目录用来练习shell, 其中有个test.log文件用来存放日志 #!/usr/bin/bash # shell文件开头, 用来指定该文件使用哪个解释器 ...
随机推荐
- virtualenvwrapper.sh: There was a problem running the initialization hooks. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenvwrapper.........(解决办法)
Linux(ubuntu)上python2与python3共存环境下,安装virtualenvwrapper后, 其环境变量被自动设置为VIRTUALENVWRAPPER_PYTHON=/usr/bi ...
- (十四)Python3 字符串格式化
Python3 字符串格式化 字符串的格式化方法分为两种,分别为占位符(%)和format方式.占位符方式在Python2.x中用的比较广泛,随着Python3.x的使用越来越广,format方式使用 ...
- add list of symbols in latex
* add list of symbols -- latex 1. createa new tex file named "toc.tex' with the following conte ...
- Leetcode 149.直线上最多的点数
直线上最多的点数 给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o ...
- JavaEE JDBC 怎么加载驱动
JDBC怎么加载驱动 @author ixenos 分析 1.JDBC是一套连接数据库的接口(放在java.util.sql.Driver类中),不同的数据库依此接口各自实现Java连接到数据库的操作 ...
- HDU 3664 (水地推)
http://acm.hdu.edu.cn/showproblem.php?pid=3664 题意:给出数字n,问n的所有的排列中满足Ai>i 数字恰好为 k的排列的个数. sl : dp dp ...
- bzoj 3173 [Tjoi2013]最长上升子序列 (treap模拟+lis)
[Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2213 Solved: 1119[Submit][Status] ...
- Django开发:(3.1)ORM:单表操作
MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需 ...
- Window Pains(poj 2585)
题意: 一个屏幕要同时打开9个窗口,每个窗口是2*2的矩阵,整个屏幕大小是9*9,每个窗口位置固定. 但是是否被激活(即完整显示出来)不确定. 给定屏幕状态,问是否可以实现显示. 分析:拓扑排序,把完 ...
- POJ1068 Parencodings 解题报告
Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two diff ...