一、概念回顾

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中各种队列和任务执行方式的组合的更多相关文章

  1. iOS 关于GCD中的队列

    GCD中队列分类及获得方式 1.串行队列  dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...

  2. 关于OC中的几种延迟执行方式

    第一种: [UIView animateWithDuration: delay: options: animations:^{ self.btn.transform = CGAffineTransfo ...

  3. 读书笔记——spring cloud 中 HystrixCommand的四种执行方式简述

    读了<Spring Cloud 微服务实战>第151-154页, 总结如下: Hystrix存在两种Command,一种是HystrixCommand,另一种是HystrixObserva ...

  4. shell中sparksql语句调试、执行方式

    1.命令方式执行sparksql查询 SQL="use mydatatable;;select count(1) from tab_videousr_onlne where p_regiio ...

  5. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

  6. IOS中延时执行方式

    本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...

  7. Lua中实现队列(高效方式)

    转自http://www.cnblogs.com/stephen-liu74/archive/2012/06/25/2417894.html 在Lua中实现队列的简单方法是使用table库函数inse ...

  8. Delphi中ADO异步执行方式

    当ADO开始处理数据后,应用程序必须等到ADO处理完毕之后才可以继续执行.但是除了同步执行方式之外,ADO也提供了异步执行的方式,允许当ADO处理时,应用程序仍然能够先继续执行.而当ADO处理数据完毕 ...

  9. shell基础概念, if+命令, shell中引用python, shell脚本的几种执行方式

    说明: 虚拟机中shell_test目录用来练习shell, 其中有个test.log文件用来存放日志 #!/usr/bin/bash      # shell文件开头, 用来指定该文件使用哪个解释器 ...

随机推荐

  1. 转载:Django之form表单

    转载: 一.使用form类创建一个表单 先定义好一个RegForm类: forms.py from django import forms # 导入forms类 class NameForm(form ...

  2. reactNative 打包那些事儿

    我们项目测试时一般是debug版本,打包上线,一般是release版本,所以在测试和打包时会走不同的方法,如上图所示. 在debug版本中,会走我们本地服务器,也就是自己电脑上的服务.在release ...

  3. Webdriver测试脚本1(打开网页并打印标题)

    案例: 启动火狐浏览器 首页打开博客园页面,打印网页标题,等待3秒 打开百度首页,打印网页标题,再等待2秒 关闭浏览器 from selenium import webdriver from time ...

  4. hihoCoder#1120 小Hi小Ho的惊天大作战:扫雷·三

    原题地址 看上去非常复杂, 实际上是这一系列最简单的一步,本质上是个搜索过程,相比于前一道题,可以不用策略三,而且题目的数据规模超级小,所以暴力搜索就能过. 把尚未确定的点放在一个unsettled列 ...

  5. [BZOJ1138][POI2009]Baj 最短回文路

    [BZOJ1138][POI2009]Baj 最短回文路 试题描述 N个点用M条有向边连接,每条边标有一个小写字母. 对于一个长度为D的顶点序列,回答每对相邻顶点Si到Si+1的最短回文路径. 如果没 ...

  6. noip模拟赛 蒜头君的兔子

    分析:直接暴力算有30分,像斐波那契那样推式子算有60分,如果想要得到100分就要用一种数列题的常见优化--矩阵了. 当前的兔子数和十年内的兔子数有关,我们需要1个1*11的矩阵,来记录当前为0岁.1 ...

  7. bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1006  Solved: 464[Submit][ ...

  8. mysql 安装与卸载

    mysql用了也好几年了,但每次安装完或者卸载完就忘记了安装步骤以及卸载步骤,因此将关键的步骤记录下来,供以后参考. 1.mysql安装 ①安装类型有typical,complete,custom,一 ...

  9. bzoj1444 有趣的游戏(AC自动机+概率dp)

    题意: 给定n个长度为l的模式串,现在要用前m个大写字母生成一个随机串,每个字符有自己的出现几率,第一次出现的字符串获胜,求最终每个字符串的获胜几率. 分析: 容易想到先把所有的字符串建成一个AC自动 ...

  10. Eclipse-Java代码规范和质量检查插件-FindBugs

    FindBugs 是由马里兰大学提供的一款开源 Java静态代码分析工具.FindBugs通过检查类文件或 JAR文件,将字节码与一组缺陷模式进行对比从而发现代码缺陷,完成静态代码分析.FindBug ...