GCD是Apple开发的一个多核编程的解决方法。
所有的调度队列都是先进先出的。因此,队列中的任务的执行顺序与其加入队列的顺序相同。
一,dispatch queue分成以下三种:
1)运行在主线程的Main queue,是一个全局可用的串行队列,通过dispatch_get_main_queue获取;任何需要刷新UI的操作都在主线程里面执行,而对于比较耗时的任务最好是放到别的线程执行。
2)并行队列global dispatch queue,通过dispatch_get_global_queue获取,我们自己不能去创建,有系统创建三个不同优先级的dispatch queue。并行队列的执行顺序与其加入队列的顺序相同。
3)串行队列serial queue一般用于按顺序同步访问,又称为私有调度队列,可创建任意数量的串行队列,各个串行队列之间是并发的。一般用在对特定资源的同步访问上。
当想要任务按照某一个特定的顺序执行时,串行队列是很有用的。串行队列在同一时间只执行一个任务。我们可以使用串行队列代替锁去保护共享的数据。和锁不同,一个串行队列可以保证任务在一个可预知的顺序下执行。 serial queue通过dispatch_queue_create创建,可以使用函数dispatch_retain和dispatch_release去控制引用计数。
二,GCD中的任务和队列
在GCD中加入了两个非常重要的概念:任务和队列。
1)任务
即操作,你想要干什么,说白了就是一段代码。在GCD中就是一个Block。所以提添加任务十分方便。任务的两种执行方式:同步和异步。
准确的说,同步(sync)和异步(async)的主要区别在于会不会阻塞当前的线程,直到Block中的任务执行完毕。
2)队列
用于存放任务。分两种:串行队列和并行队列。
放到串行队列的任务,GCD会FIFO(先进先出)地取出一个,执行一个,然后再取出下一个执行;
放到并行队列的任务,GCD也FIFO(先进先出)地取出来,但不同的是,他取出一个就会放到别的线程,然后再取出一个放到另一个线程。这样由于取出的动作很快,忽略不计,看起来所有的任务都是同时执行的。不过需要注意的是,GCD会根据系统资源控制并行数量,所以如果任务很多,他并不会让所有任务同时执行。
三,GCD的用法
// 后台执行:
dispatch_async(dispatch_get_global_queue(0,0), ^{
// something
});
// 主线程执行:
dispatch_async(dispatch_get_main_queue(), ^{
// something
});
// 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
});
// 延迟2秒执行:
double delayInSeconds =2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// code to be executed on the main queue after delay
});
// 自定义dispatch_queue_t
dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
dispatch_async(urls_queue, ^{
// your code
});
dispatch_release(urls_queue);
// 合并汇总结果
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程一
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程二
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// 汇总结果
});
四,线程死锁
线程死锁,请参考:
http://www.jianshu.com/p/0b0d9b1f1f19
http://www.brighttj.com/ios/ios-gcd-deadlock.html