一、概念回顾

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. C++解决大数组问题

    今天写一个C++小程序,竟然出现:"VS 未经处理的异常: 0xC00000FD: Stack overflow" 查了一下,普通数组变量是在堆栈中保存的,而堆栈空间有限,故出此错 ...

  2. 从Hadoop框架讨论大数据

    [Hadoop是什么?] 1)Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构. 2)主要解决,海量数据的存储和海量数据的分析计算问题. 3)广义上来说,HADOOP 通常是指一 ...

  3. Lucene的分词_中文分词器介绍

    Paoding:庖丁解牛分词器.已经没有更新了. MMSeg:搜狗的词库. MMSeg分词器的一些截图: 步骤: 1.导入包 2.创建的时候使用MMSegAnalyzer分词器

  4. git-github 提示Permission denied (publickey) (windows)

    这种绝大多数情况是由于公钥设置的问题. 1.生成公钥 参考地址:https://help.github.com/articles/generating-a-new-ssh-key-and-adding ...

  5. get方法和set方法

    定义一个类,该类有一个私有成员变量,通过构造方法将其进行赋初值,并提供该成员的getXXX()和setXXX()方法 提示:假设有private String name;则有 public void  ...

  6. noip模拟赛 分组

    分析:暴力分挺多,也挺好想的,个人感觉两个特殊性质没什么卵用. 对于K=1,n ≤ 1024的情况,从后往前贪心地分,如果能和上一组分在一起就分在一起,否则就再开一组,这样可以保证字典序最小.ai ≤ ...

  7. bzoj3304[Shoi2005]带限制的最长公共子序列 DP

    题意:给出三个序列,求出前两个的公共子序列,且包含第三个序列,要求长度最长. 这道题目怎么做呢,f[i][j]表示a串1-i,b串1-j的最长,g[i][j]表示a串i-n,b串j-m最长, 那么只需 ...

  8. string数据类型操作【四】

    keys *    用于查找所有的key值 exists mykey     #判断该键是否存在,存在返回1,否则返回0. del mykey        删除键(存在就删除返回1,不存在返回为0) ...

  9. easyui datagrid-detailview 嵌套高度自适应

    实现效果 原因 异步加载,明细展开时,可能会遇到父列表不能自动适应子列表高度的变化 具体代码 $('#centerdatagrid').datagrid({ url:'${ctx}/offer/off ...

  10. symfony 使用原始sql

    $this->get('database_connection')->fetchAll('select * from book where book.id=3')