多线程 - 06.GCD概述
2015-08-21 20:23
211 查看
1.GCD简介
全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”纯C语言,但是提供了非常多功能强大的函数,非常方便
GCD的优势
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
2.任务和队列
GCD中有2个核心概念任务:执行什么操作
队列:用来存放任务
GCD的使用就2个步骤
定制任务:确定想做的事情
将任务添加到队列中
GCD会自动将队列中的任务取出,放到对应的线程中执行
任务的取出遵循队列的FIFO原则:先进先出,后进后出
3.执行任务
GCD中有2个用来执行任务的常用函数用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); // queue:队列 block:任务
用异步的方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
同步和异步的区别
同步:只能在当前线程中执行任务,不具备开启新线程的能力
异步:可以在新的线程中执行任务,具备开启新线程的能力
注意点:同步函数一定不会开启新线程,异步函数只是具备开启新线程的能力,并不一定会开启新线程
GCD中还有个用来执行任务的函数:
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block); //在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行 // 注意:这个queue不能是全局的并发队列
4.队列的类型
GCD的队列可以分为2大类型并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
5.相关术语说明
有4个术语比较容易混淆:同步、异步、并发、串行同步和异步主要影响:能不能开启新的线程由同步或异步函数决定,和队列没有半毛钱关系
同步:只是在当前线程中执行任务,不具备开启新线程的能力
异步:可以在新的线程中执行任务,具备开启新线程的能力
并发和串行主要影响:任务的执行方式
并发:允许多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
6.队列的创建
并发队列//使用dispatch_queue_create函数创建队列 dispatch_queue_t // 队列类名 dispatch_queue_create(const char *label, // 队列名称 dispatch_queue_attr_t attr); // 队列的类型 //创建并发队列 dispatch_queue_t queue = dispatch_queue_create("zj.queue", DISPATCH_QUEUE_CONCURRENT);
GCD默认已经提供了全局的并发队列,供整个应用使用,可以无需手动创建
//使用dispatch_get_global_queue函数获得全局的并发队列 /* 全局并发队列的优先级(iOS8以前) #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中) #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台 全局并发队列的服务质量(iOS8以后) * - QOS_CLASS_USER_INTERACTIVE 0x21 用户交互(用户迫切想执行任务) * - QOS_CLASS_USER_INITIATED 0x19 用户需要 * - QOS_CLASS_DEFAULT 0x15 默认 * - QOS_CLASS_UTILITY 0x11 工具(低优先级, 苹果推荐将耗时操作放到这种类型的队列中) * - QOS_CLASS_BACKGROUND 0x09 后台 * - QOS_CLASS_UNSPECIFIED 0x00 没有设置 */ dispatch_queue_t dispatch_get_global_queue( dispatch_queue_priority_t priority, // 队列的优先级 unsigned long flags); // 此参数暂时无用,用0即可 //获得全局并发队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
串行队列
GCD中获得串行有2种途径
使用dispatch_queue_create函数创建串行队列
// 创建串行队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL) dispatch_queue_t queue = dispatch_queue_create("zj.queue", NULL);
使用主队列(跟主线程相关联的队列)
主队列是GCD自带的一种特殊的串行队列
放在主队列中的任务,都会放到主线程中执行
使用dispatch_get_main_queue()获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
7.各种队列的执行效果
GCD函数 | 并发队列 | 手动创建的串行队列 | 主队列 |
---|---|---|---|
同步(sync) | 1.没有开启新线程2.串行执行任务 | 1.没有开启新线程列2.串行执行任务 | 1.没有开启新线程2.串行执行任务 |
异步(async) | 1.有开启新线程2.并发执行任务 | 1.有开启新线程2.串行执行任务 | 1.没有开启新线程2.串行执行任务 |
使用sync函数往当前主队列中添加任务,会造成死锁
相关文章推荐
- hash 冲突处理
- java集合
- osx快捷键表示图
- 五点三次平滑法滤波 C 和 matlab代码
- 五点三次平滑法滤波 C 和 matlab代码
- Compare Version Numbers
- 深入理解JavaScript系列(35):设计模式之迭代器模式
- javascript深入理解js闭包
- iPhone屏幕尺寸
- android中TextView、TextEdit和Button的用法以及draw9patch
- XE5 Android 开发数据访问server端
- 重载小记
- 康定
- PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询
- 配置opencv环境
- NTP工作原理
- Jenkins自动编译Android Studio创建的工程
- 什么是窗口?
- datagridview里面有combox避免双击两次的写法
- LightOJ 1317 第六周比赛A题