`
java-mans
  • 浏览: 11455878 次
文章分类
社区版块
存档分类
最新评论

GCD小结

 
阅读更多

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

  • dispatch_once

如果没有记错的话,在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

有时候我们需要等个几秒钟然后做个动画或者给个提示,这时候可以用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

执行某个代码片段若干次。

dispatch_apply(10, globalQ, ^(size_t index) {
    // do sth. 10 times
});

  • dispatch group

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_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异步获取图片

    GCD 源码分析.pdf

    GCD 源码分析.pdf

    GCD最大公约数

    GCD最大公约数int main() { int a,b; int c; while(cin>>a>>b) { c=gcd(a,b); cout; } return 0; }

    二进制gcd算法

    二进制gcd算法,为算法导论后面的思考题

    GCD编程逻辑

    gcd多核编程

    gcd方法代码测试

    gcd的基础方法使用,线程和队列的使用 gcd的基础方法使用,线程和队列的使用

    GCD的高级用法

    GCD的一些高级用法,是不容错过的多线程开发学习材料

    iOS GCD多核编程

    1.iOS多核任务,比NSThead更易用的异步方法 2.展示了如何停止一个GCD方法

    Behavioral GCD in Verilog

    Behavioral GCD in Verilog,用于对两个数求最大公约数

    iOS GCD timer 计时器

    iOS GCD timer 计时器 自己封装直接使用即可 GCD实现的计时器解决timer内存不好管理问题。

    计算GCD的简单java程序

    创建最常用的除数计算器;。。。GCD计算器允许您快速查找一组数字的最大公约数;。。。当两个数的最大公约数为1时,这两个数称为互质或相对素数。

    gcdtest1示例源码

    GCD的示例源码,使用串行队列实现简单的预加载

    GCD IOS example

    Grand Central Dispatch (GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更...

    swift-GCD使用大全

    葵花宝典之GCD常用和不常用API说明和Demo演示,让你轻松不费脑力的理解GCD的应用场景和操作姿势

    GCD使用的相关方法

    上传代码中是GCD使用的一些基础和延伸的方法,对于了解GCD的用法,很有帮助。

    iOS GCD详解

    iOS GCD详解,让你了解并掌握GCD的使用

    iOS GCD 开发教程 完整版

    iOS GCD 开发教程 完整版 有需要的同学看看 iOS GCD 开发教程 完整版 有需要的同学看看 iOS GCD 开发教程 完整版 有需要的同学看看

    GCD.rar_gcd

    最大公约数的计算,各个源描述的编译顺序:gcd.vhd,gcd_stim.vhd

    GCD 总结-队列和任务的理解

    GCD 是苹果开发的应对多核编程,本实例总结了 GCD 三种队列的获取和创建,以及两种执行任务的方法。

    GCD总结代码

    关于GCD的用法、注意事项、难点的总结代码。

Global site tag (gtag.js) - Google Analytics