0. Brief Introduction
GCD,全称Grand Central Dispath,是苹果开发的一种支持并行操作的机制。它的主要部件是一个FIFO队列和一个线程池,前者用来添加任务,后者用来执行任务。
GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行(但不保证一定先执行结束)。
通过与线程池的配合,dispatch queue分为下面两种:
- Serial Dispatch Queue -- 线程池只提供一个线程用来执行任务,所以后一个任务必须等到前一个任务执行结束才能开始。
- Concurrent Dispatch Queue -- 线程池提供多个线程来执行任务,所以可以按序启动多个任务并发执行。
1. Basic Management
我们可以通过dispatch_queue_cretae来创建队列,然后用dispatch_release释放。比如下面两段代码分别创建串行队列和并行队列:
dispatch_queue_t serialQ = dispatch_queue_create("eg.gcd.SerialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQ, ^{
// Code here
});
dispatch_release(serialQ);
dispatch_queue_t concurrentQ = dispatch_queue_create("eg.gcd.ConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQ, ^{
// Code here
});
dispatch_release(concurrentQ);
而系统默认就有一个串行队列main_queue和并行队列global_queue:
dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t mainQ = dispatch_get_main_queue();
通常,我们可以在global_queue中做一些long-running的任务,完成后在main_queue中更新UI,避免UI阻塞,无法响应用户操作:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// long-running task
dispatch_async(dispatch_get_main_queue(), ^{
// update UI
});
});
上面提到dispatch_async这个接口,用来提交blcok给指定queue进行异步执行。这个接口会在成功提交block后立即返回,然后继续执行下去。由于block是定义在栈上的,所以需要将其复制到堆上,见这里。
与之相对应的是dispatch_sync接口,提交block以供同步执行。这个接口会等到block执行结束才返回,所以不需要复制block。So,如果在调用该接口在当前queue上指派任务,就会导致deadlock。维基百科上给了段示例代码:
dispatch_queue_t exampleQueue = dispatch_queue_create("com.example.unique.identifier", NULL );
dispatch_sync( exampleQueue,^{
dispatch_sync( exampleQueue,^{
printf("I am now deadlocked...\n");
});});
dispatch_release( exampleQueue );
如果追求的是并发,那么dispatch_sync有什么用呢?关于dispatch_sync的用途,SO上有讨论。
2. Normal Control
如果没有记错的话,在iOS Con 2012上,大众点评的同学分享了个Topic叫《iOS开发最佳实践》,开篇讲singleton实现的演进(怎么演进都有可以挑的刺),后面转折说要把精力放到用户看得到的地方。
如果把singleton和best practice放在一起,那么我很容易联想到dispatch_once这个函数,它可以保证整个应用程序生命周期中某段代码只被执行一次!
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
});
有时候我们需要等个几秒钟然后做个动画或者给个提示,这时候可以用dispatch_after这个函数:
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_set_target_queue
通过dispatch_set_target_queue函数可以设置一个dispatch
queue的优先级,或者指定一个dispatch source相应的事件处理提交到哪个queue上。
dispatch_set_target_queue(serialQ, globalQ);
执行某个代码片段若干次。
dispatch_apply(10, globalQ, ^(size_t index) {
// do sth. 10 times
});
Dispatch Group机制允许我们监听一组任务是否完成:
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, concurrentQ, blk0);
dispatch_group_async(group, concurrentQ, blk1);
dispatch_group_async(group, concurrentQ, blk2);
dispatch_group_notify(group, mainQ, ^{
// update UI
});
dispatch_release(group);
或者说同步地等待一段时间看是否结束:
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC);
dispatch_group_wait(group, time);
通过dispatch_barrier_async函数提交的任务会等它前面的任务执行结束才开始,然后它后面的任务必须等它执行完毕才能开始。
dispatch_async(concurrentQ, blk0);
dispatch_async(concurrentQ, blk1);
dispatch_barrier_async(concurrentQ, blk_barrier);
dispatch_async(concurrentQ, blk2);
这份官方文档很清晰地按功能为GCD相关函数进行了分类。
Jason Lee @ Hangzhou
原文链接:http://blog.csdn.net/jasonblog/article/details/7816999
分享到:
相关推荐
GCD异步获取图片
GCD 源码分析.pdf
GCD最大公约数int main() { int a,b; int c; while(cin>>a>>b) { c=gcd(a,b); cout; } return 0; }
二进制gcd算法,为算法导论后面的思考题
gcd多核编程
gcd的基础方法使用,线程和队列的使用 gcd的基础方法使用,线程和队列的使用
GCD的一些高级用法,是不容错过的多线程开发学习材料
1.iOS多核任务,比NSThead更易用的异步方法 2.展示了如何停止一个GCD方法
Behavioral GCD in Verilog,用于对两个数求最大公约数
iOS GCD timer 计时器 自己封装直接使用即可 GCD实现的计时器解决timer内存不好管理问题。
创建最常用的除数计算器;。。。GCD计算器允许您快速查找一组数字的最大公约数;。。。当两个数的最大公约数为1时,这两个数称为互质或相对素数。
GCD的示例源码,使用串行队列实现简单的预加载
Grand Central Dispatch (GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更...
葵花宝典之GCD常用和不常用API说明和Demo演示,让你轻松不费脑力的理解GCD的应用场景和操作姿势
上传代码中是GCD使用的一些基础和延伸的方法,对于了解GCD的用法,很有帮助。
iOS GCD详解,让你了解并掌握GCD的使用
iOS GCD 开发教程 完整版 有需要的同学看看 iOS GCD 开发教程 完整版 有需要的同学看看 iOS GCD 开发教程 完整版 有需要的同学看看
最大公约数的计算,各个源描述的编译顺序:gcd.vhd,gcd_stim.vhd
GCD 是苹果开发的应对多核编程,本实例总结了 GCD 三种队列的获取和创建,以及两种执行任务的方法。
关于GCD的用法、注意事项、难点的总结代码。