一、简介:
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并行任务。在Mac OS X 10.6雪豹中首次推出,也可在IOS 4及以上版本使用。
GCD是一个替代诸如NSThread等技术的很高效和强大的技术。GCD完全可以处理诸如数据锁定和资源泄漏等复杂的异步编程问题。GCD的工作原理是让一个程序,根据可用的处理资源,安排他们在任何可用的处理器核心上平行排队执行特定的任务。这个任务可以是一个功能或者一个程序段。
GCD仍然在一个很低的水平使用线程,但是它不需要程序员关注太多的细节。GCD创建的队列是轻量级的,苹果声明一个GCD的工作单元需要由15个指令组成。也就是说创造一个传统的线程很容易的就会需要几百条指令。
GCD中的一个任务可被用于创造一个被放置于队列的工作项目或者事件源。如果一个任务被分配到一个事件源,那么一个由功能或者程序块组成的工作单元会被放置于一个适当的队列中。苹果公司认为GCD相比于普通的一个接一个的执行任务的方式更为有效率。(来自百科)
二、队列
GCD的所有的调度队列都是先进先出队列,因此,队列中的任务的开始的顺序和添加到队列中的顺序相同。我们可以将部分独立运行的任务添加到对列,由系统管理执行。
GCD队列主要有三种,系统主队列 main_queue、全局并发队列 global_queue和自定义队列
- 并发队列 队列中的任务必须在前一个任务开始后才能执行
- 同步串行队列:队列的执行任务与主线程是同步的,会阻塞主线程
- 异步串行队列:队列的执行任务与主线程是异步的
- 串行队列 队列中的任务必须在前一个任务结束后才能执行(可替代线程锁)
- 同步串行队列:队列的执行任务与主线程是同步的,会阻塞主线程
- 异步串行队列:队列的执行任务与主线程是异步的
三、队列的创建
- 自定义串行队列,提交同步任务
//1.创建串行队列、提交同步任务 dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ //code 任务一 }); dispatch_sync(queue, ^{ //code 任务二 });
队列中的任务是同步出列的,任务一执行结束后执行任务二。这种类型的任务与主线程是同步的,会阻塞主线程
- 自定义串行队列,提交异步任务
//1.创建串行队列、提交异步任务 dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{ //code 任务一 }); dispatch_async(queue, ^{ //code 任务二 });
队列的任务是同步出列,任务一执行结束后执行任务二。该类型的任务与主线程是并发执行的,不会阻塞主线程
- 自定义并行队列,提交同步任务
// 创建并行队列、提交同步任务 dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //code 任务一 }); dispatch_async(queue, ^{ //code 任务二 });
队列的任务是异步出列,任务的出列顺序按先进先出的顺序执行,既任务一出列后任务二接着出列(任务一与任务二又是同步的),与主线程同步,会阻塞主线程
- 自定义并行队列,提交异步任务
//创建并行队列、提交异步任务 dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //code 任务一 }); dispatch_async(queue, ^{ //code 任务一 });
任务一出列后任务二才可以出列,各任务之间是异步的,不会阻塞主线程
- 在主队列提交同步任务
//在主队列提交同步任务 dispatch_sync(dispatch_get_main_queue(), ^{ //code });
阻塞主线程
- 在主队列提交异步任务
//在主队列提交异步任务 dispatch_async(dispatch_get_main_queue(), ^{ //code任务 });
- 在全局队列提交同步任务
//在全局队列提交同步任务 dispatch_sync(dispatch_get_global_queue(0, 0), ^{ //code });
- 在全局队列提交异步任务
//在全局队列提交异步任务 dispatch_async(dispatch_get_global_queue(0, 0), ^{ //code });
dispatch_get_gloabal_queue 的第一个参数为枚举类型(默认为0),决定任务的优先级 ,第二个参数为Apple保留参数,传0
#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(后台任务,优先级最低)
四、总结
队列的类型决定了队列任务的执行方式(主队列是一个串行队列)。一般把会阻塞主线程的任务提交到异步并行队列当中。