全局队列的并发执行

for(id obj in array)
[self doSomethingIntensiveWith:obj];

假设,每个元素要做的事情-doSomethingIntensiveWith: 是线程安全的且可以同时并发执行多个。一个array通常包含多个元素,这样的话,我们可以很简单地使用GCD来平行运算:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
for(id obj in array)
dispatch_async(queue, ^{
[self doSomethingIntensiveWith:obj];
});

这样充分利用了多核系统的性能。

有时候,我们需要在完成对数组的每一个数据操作之后,再对数组整体进行操作,那么就有一个问题,什么时候,这些数组的数据的并发执行任务都完成了?

dispatch group

解决这个问题的一种方法是使用dispatch group。一个dispatch group可以用来将多个block组成一组以监测这些Block全部完成或者等待全部完成时发出的消息。使用函数dispatch_group_create来创建,然后使用函数dispatch_group_async来将block提交至一个dispatch queue,同时将它们添加至一个组。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_group_t group = dispatch_group_create();
for(id obj in array)
dispatch_group_async(group, queue, ^{
[self doSomethingIntensiveWith:obj];
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group); [self doSomethingWith:array];

如果后续的对数组的整体处理也是可以异步的,那么可以这样:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_group_t group = dispatch_group_create();
for(id obj in array)
dispatch_group_async(group, queue, ^{
[self doSomethingIntensiveWith:obj];
});
dispatch_group_notify(group, queue, ^{
[self doSomethingWith:array];
});
dispatch_release(group);

如果对数组的处理-doSomethingWith:需要在主线程中执行,比如操作GUI,那么我们只要将main queue而非全局队列传给dispatch_group_notify函数就行了。

dispatch_apply

同步执行,GCD提供了一个简化方法叫做dispatch_apply。该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,指定的次数的Block将会被异步执行,dispatch_apply函数会等待全部处理执行结束,接着进行后面的代码序列。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_apply([array count], queue, ^(size_t index){
[self doSomethingIntensiveWith:[array objectAtIndex:index]];
});
[self doSomethingWith:array];

dispatch_apply函数是没有异步版本的,实现异步要用dispatch_async函数将所有代码推到后台实现异步。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_async(queue, ^{
dispatch_apply([array count], queue, ^(size_t index){
[self doSomethingIntensiveWith:[array objectAtIndex:index]];
});
[self doSomethingWith:array];
});
dispatch_queue_t queue = dispatch_get_global_queu(, );
dispatch_apply(, queue, ^(size_t index){
NSLog(@"%zu", index);
});
NSLog(@"done");

执行结果:


done
  • 第一个参数为重复次数
  • 第二个参数为追加对象的Dispatch Queue
  • 第三个参数为追加的处理。

由于dispatch_apply函数与dispatch_sync函数相同,会等待处理执行结束,因此推荐在dispatch_async函数中非同步地执行dispatch_apply函数

NSArray *array = @[@"", @"", @"", @"", @"", @""];
dispatch_queue_t queue = dispatch_get_global_queue(, ); dispatch_async(queue, ^{ dispatch_apply([array count], queue, ^(size_t index) { NSLog(@"%zu : %@", index, [array objectAtIndex:index]);
}); dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"currentThread = %@", [NSThread currentThread]);
NSLog(@"done");
});
});

GCD系列 之(二): 多核心的性能的更多相关文章

  1. 完整具体解释GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

    原创Blog,转载请注明出处 本文阅读的过程中,如有概念不懂,请參照前专栏中之前的文章,假设还有疑惑,请留言. 这是我关于GCD专栏的地址 http://blog.csdn.net/column/de ...

  2. Ajax系列之二:核心对象XMLHttpRquest

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhanghongjie0302/article/details/31432939           ...

  3. GCD介绍(二): 多核心的性能

    GCD介绍(二): 多核心的性能  概念         为了在单一进程中充分发挥多核的优势,我们有必要使用多线程技术(我们没必要去提多进程,这玩意儿和GCD没关系).在低层,GCD全局dispatc ...

  4. 当我们说线程安全时,到底在说什么——Java进阶系列(二)

    原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...

  5. Sql Server来龙去脉系列之二 框架和配置

    本节主要讲维持数据的元数据,以及数据库框架结构.内存管理.系统配置等.这些技术点在我们使用数据库时很少接触到,但如果要深入学习Sql Server这一章节也是不得不看.本人能力有限不能把所有核心的知识 ...

  6. NLP+词法系列(二)︱中文分词技术简述、深度学习分词实践(CIPS2016、超多案例)

    摘录自:CIPS2016 中文信息处理报告<第一章 词法和句法分析研究进展.现状及趋势>P4 CIPS2016 中文信息处理报告下载链接:http://cips-upload.bj.bce ...

  7. Storm 系列(二)实时平台介绍

    Storm 系列(二)实时平台介绍 本章中的实时平台是指针对大数据进行实时分析的一整套系统,包括数据的收集.处理.存储等.一般而言,大数据有 4 个特点: Volumn(大量). Velocity(高 ...

  8. C#多线程编程系列(二)- 线程基础

    目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...

  9. C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点

    C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点   第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...

  10. 【转】RHadoop实践系列之二:RHadoop安装与使用

    RHadoop实践系列之二:RHadoop安装与使用 RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析.Hadoop主要用来存储海量数据,R语言完成MapReduce 算法, ...

随机推荐

  1. HTML5学习+javascript学习:打飞机游戏简介以及Model层

    本着好记性不如烂博客以及分享成功的喜悦和分享失败的苦楚,今天我来分享下一个练手项目:打飞机游戏~从小就自己想做游戏,可是一直没有机会.HTML5给了我们这个平台,这个平台可以有很多以前想都不敢想的东西 ...

  2. jQuery Mobile (整合版)

    jQuery Mobile (整合版) 前言 为了方便大家看的方便,我这里将这几天的东西整合一下发出. 里面的例子请使用手机浏览器查看. 什么是jQuery Mobile? jquery mobile ...

  3. 三种工厂模式的分析以及C++实现

    三种工厂模式的分析以及C++实现 以下是我自己学习设计模式的思考总结. 简单工厂模式 简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型, ...

  4. HDU 2073 无限的路

    Problem Description 甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形: 甜甜的好朋友蜜蜜发现上面的图还 ...

  5. Hamilton

    import java.util.Vector; class Hamilton { int start; int a[][]; int len; int x[]; // 记录回路 boolean fl ...

  6. ASP.NET上传大文件出现网页无法显示的问题

    使用FileUpload上传的时候,默认允许大小是4M,而当小于4M的时候正常运行:当超过4M将显示网页无法显示.解决方法如下: 在web.config中的<system.web>< ...

  7. 解决 jQuery.UI.Resizable aspectRatio在init后无法重新设置

    一.背景  在jQuery1.9.x版本之前,存在aspectRatio在Resizable方法init之后,无法再次修改aspectRatio的boolean值. 二.解决方案 // 用于fix j ...

  8. 安装vsftp流程整理

    昨天装个FTP,发现之前写的一篇操作日志太简陋了,重新整理了下记在这儿 # 安装 VSFTP yum -y install vsftpd # 创建FTP日志文件路径 touch /var/log/vs ...

  9. http协议的状态码 403 404 301 302 200 500 502 504 报错显示

    在网站建设的实际应用中,容易出现很多小小的失误,就像MySQL当初优化不到位,影响整体网站的浏览效果一样,其实,网站的常规http状态码的表现也是一样,Google无法验证网站几种解决办法,提及到由于 ...

  10. LoadLibraryW 参数问题

    error C2664: "LoadLibraryW": 不能将参数1 从"const char [8]"转换为"LPCWSTR" 右击工程 ...