全局队列的并发执行

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. 使用C#开发ActiveX控件

    使用C#开发ActiveX控件(新) 前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能,以增强浏览器端的动 ...

  2. .Net 中的反射机制

    .Net 中的反射机制 概述反射 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象. 反射机制允许程序在执行过程中动态地添加各种功能. 运行时类型标识 运行时类型标 ...

  3. Big Data Ingestion and streaming product introduction

    Flume Flume isdistributed system for collecting log data from many sources, aggregating it,and writi ...

  4. 从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft.Server.manageDTS

    从ICassFactory为CLSID为{17BCA6E8-A950-497E-B2F9-AF6AA475916F}的COM组件创建实例失败,原因是出现以下错误:c001f011.(Microsoft ...

  5. 框架基础:ajax设计方案(三)---集成ajax上传技术

    之前发布了ajax的通用解决方案,核心的ajax发布请求,以及集成了轮询.这次去外国网站逛逛,然后发现了ajax level2的上传文件,所以就有了把ajax的上传文件集成进去的想法,ajax方案的l ...

  6. 你的MongoDB Redis设置用户名密码了吗?看看shodan这款邪恶的搜索引擎吧!~

    早上看新闻的时候看到了个醒目的新闻 开源中国:MongoDB 赎金事件持续发酵,究竟是谁之过? 博客园:MongoDB数据库勒索,中国受害者数量超乎你的想象,SOS! 1. 由于自己之前做过的项目,R ...

  7. 关于SQL 数据表中的密码加密

    首先,都知道一个字节(byte)等于八位二进制数.在数据表中将密码字段设置为binary类型,再结合哈希散列运算可以实现密码加密. 下面介绍下binary 和 varbinary: binary 和  ...

  8. 利用fiddler将本地网页放到某个域下

    注: 1)在学习慕课网课程<搜索框制作>中遇到如题困难,查找资料后解决,做此记录.课程网址http://www.imooc.com/video/263. 2)建议同时去学习慕课网课程< ...

  9. php学习笔记——基础知识(2)

    9.PHP语句 if 语句 - 如果指定条件为真,则执行代码 if...else 语句 - 如果条件为 true,则执行代码:如果条件为 false,则执行另一端代码 if...else if.... ...

  10. maven项目添加websocket

    最近由于项目业务需求,需要用到websocket来实现即时信息的推送,学习了一下websocket,网上搜了一下学习教程,很多版本看的我云里雾里,最后选择用tomcat提供的最新版本(tomcat 启 ...