GCD 多线程技术
Grand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用
的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成
必要的线程并计划执行任务。由于线程管理是作为系统的一部分来实现的,因此可以统一管理,也可以执行任务,
这样就比以前的线程更有效率。
GCD API
1. Dispatch Queue 队列
队列有两种类型:
Serial Dispatch Queue 串行队列,使用一个线程,按照追加的顺序(先进先出FIFO)执行处理。多个串行队列之间是并行处理的。
Concurrent Dispatch Queue 并行队列,使用多个线程,并发处理
2.diapatch_queue_create
创建 Serial Queue:
dispatch_queue_t mySerailQueue = dispatch_queue_create("com.r.dispatchSerailQueue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t myConcurrentQueue = dispatch_queue_create("com.r.dispatchConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
第一个参数是指定 Serial dispatch queue 的名称。该名称在Xcode和Instruments的调试器中作为Dispatch Queue名称.
第二个参数是生成Dispatch Queue的类型,如果是NULL 或者 DISPATCH_QUEUE_SERIAL生成串行队列,
指定为DISPATCH_QUEUE_CONCURRENT生成并发队列.
3.Main Dispatch Queue/Global Dispatch Queue
获取系统标准提供的Dispatch Queue。
Main Dispatch Queue是在主线程执行的dispatch queue, Main Dispatch Queue是一个Serail Dispatch Queue。追加到Main Dispatch Queue的处理在主线程的RunLoop中执行。一般将用户界面更新等必需要在主线程中执行的处理追加到Main Dispatch Queue中。
Global Dispatch Queue是所有应用程序都能过使用的Concurrent Dispatch Queue。没有必要通过dispatch_queue_create函数逐个创建Concurrent Dispatch Queue,只要获取Global Dispatch Queue使用即可。Global Dispatch Queue有四个优先级
| 名称 | Dispatch Queue的种类 | 说明 |
|---|---|---|
| Main Dispatch Queue | Serial Dispatch Queue | 主线程执行 |
| Global Dispatch Queue(High Priority) | Concurrent Dispatch queue | 执行优先级:高(最高) |
| Global Dispatch Queue(Default Priority) | Concurrent Dispatch queue | 执行优先级:默认 |
| Global Dispatch Queue(Low Priority) | Concurrent Dispatch queue | 执行优先级:低 |
| Global Dispatch Queue(Background Priority) | Concurrent Dispatch queue | 执行优先级:后台 |
获取Dispatch Queue方法:
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue(); dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, );
使用Main Dispatch Queue 和 Global Dispatch Queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
/**
* 可并行处理的任务TODO
*/
dispatch_async(dispatch_get_main_queue(), ^{
/**
* 主线程执行
*/
});
});
4. dispatch_after
dispatch_after表示在指定的时间之后追加处理到Dispatch Queue。并不是指定时间后执行处理。
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"等待3秒后执行");
});
虽然在有严格时间到要求下使用时会出现问题,但在大致延迟执行处理时,该函数还是有效的。
5.dispatch_suspend/dispatch_resume
当追加大量处理到Dispatch Queue时,在追加处理到过程中,有时希望不执行已追加的处理。在这种情况下只要挂起Dispatch Queue即可。
dispatch_suspend 函数挂起指定的Dispatch Queue
dispatch_resume 函数恢复指定的Dispatch Queue
这些函数对已经执行的处理没有影响,挂起后,追加到Dispatch Queue中处理在此之后暂停执行,而恢复使得这些处理继续执行。
6.Dispatch Group
在追加到Dispatch Queue中的多个处理全部结束后想执行结束处理.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
for (int i=; i<; i++) {
NSLog(@"");
}
});
dispatch_group_async(group, queue, ^{
for (int i=; i<; i++) {
NSLog(@"");
}
});
dispatch_group_async(group, queue, ^{
for (int i=; i<; i++) {
NSLog(@"");
}
});
//最后执行4444
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"");
});
NSLog(@"");
7. dispatch_barrier_async
dispatch_async(queue, ^{
//读文件
});
dispatch_async(queue, ^{
//读文件
});
//使用dispatch_barrier_async避免数据竞争
dispatch_barrier_async(queue, ^{
//写文件
});
dispatch_async(queue, ^{
//读文件
});
dispatch_async(queue, ^{
//读文件
});
一个dispatch barrier 允许在一个并发队列中创建一个同步点。当在并发队列中遇到一个barrier, 他会延迟执行barrier的block,
等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行。 之后, 队列继续正常的执行操作。
调用这个函数总是在barrier block被提交之后立即返回,不会等到block被执行。当barrier block到并发队列的最前端,
他不会立即执行。相反,队列会等到所有当前正在执行的blocks结束执行。到这时,barrier才开始自己执行。
所有在barrier block之后提交的blocks会等到barrier block结束之后才执行。
这里指定的并发队列应该是自己通过dispatch_queue_create函数创建的。
如果你传的是一个串行队列或者全局并发队列,这个函数等同于dispatch_async函数。
8.dispatch_apply
dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API。
该函数按指定的次数将指定的Block追加到Dispatch Queue中,并等待全部处理执行结束。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_apply(, queue, ^(size_t index) {
NSLog(@"%zu", index);//并行
});
//最后执行
NSLog(@"");
9. Dispatch Semaphore
信号量:就是一种可用来控制访问资源的数量的标识,设定了一个信号量,在线程访问之前,加上信号量的处理,则可告知系统按照我们指定的信号量数量来执行多个线程。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
/**
* 生成Dispatch Semaphore
* Dispatch Semaphore 的计数初始值设定为1
* 保证可访问NSMutableArray类对象的线程同时只有一个
*/
dispatch_semaphore_t semaphore = dispatch_semaphore_create();
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int i=; i<; i++) {
dispatch_async(queue, ^{
/**
* 等待Dispatch Semaphore
一直等待,直到Dispatch Semaphore 的计数的值达到大于等于1
*/
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
/**
* 由于Dispatch Semaphore 的计数达到大于等于1
所以Dispatch Semaphore 的计数值减去1
dispatch_semaphore_wait函数执行返回
即执行到此时Dispatch Semaphore的计数值恒为00
由于可访问NSMutableArray类对象的线程数只有1个
因此可安全的进行更新
*/
[array addObject:[NSNumber numberWithInt:i]];
/**
* 排他控制处理结束
所以通过dispatch_semaphore_signal函数
将DispatchSemaphore的计数值加1
如果有通过dispatch_semaphore_wait函数
等待Dispatch Semaphore的计数值增加的线程
就由最先等待的线程执行。
*/
dispatch_semaphore_signal(semaphore);
});
}
GCD 多线程技术的更多相关文章
- [Xcode 实际操作]八、网络与多线程-(22)使用GCD多线程技术异步下载图片
目录:[Swift]Xcode实际操作 本文将演示如何使用使用GCD多线程技术异步下载图片. Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法 ...
- 多线程技术 NSThread & NSOperation & GCD
多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...
- iOS的三种多线程技术NSThread/NSOperation/GCD
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...
- iOS- NSThread/NSOperation/GCD 三种多线程技术的对比及实现
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ...
- iOS- NSThread/NSOperation/GCD 三种多线程技术的对比及实现 -- 转
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ...
- NSThread/NSOperation/GCD 三种多线程技术
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ...
- iOS多线程技术方案
iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...
- iOS开发之多线程技术
本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...
- iOS多线程技术
iOS多线程技术主要分配NSThread.NSOperation和GCD.下边来简单的介绍一下吧. 随性一点,就不按照顺序来了.所以先介绍一下NSOperation. ---------------- ...
随机推荐
- sql 传入参数为逗号分隔的字符串处理方法
写了个存储过程,中间用到了类似这种写法 Select * From User Where ID In('1,2,3') 其中'1,2,3'是从外面传进来的参数,就这样执行报错:'1,2,3'转换为in ...
- AngularJS开发人员最常犯的10个错误
简介AngularJS是目前最为活跃的Javascript框架之一,AngularJS的目标之一是简化开发过程,这使得AngularJS非常善于构建小型app原型,但AngularJS对于全功能的客户 ...
- Android碎笔录1——基本布局
刚开始学Android开发的时候,没有H5的基础总是分不清android布局文件的用法,真正要学会android布局还是得实战一次,下面不多说,直接上代码. 这是一个登陆界面,LinerLayout嵌 ...
- bootstrap-table 分页增删改查之一(分页)
记录一下 bootstrap-table插件的使用 先看下效果图 首先是导入js <!--js jquery --> <script type="text/javascri ...
- CSS中的line-height
基本概念 行高.行距 行高是指文本行基线间的垂直距离.那什么是基线呢?记不记得vertical-align属性有个baseline值,这个baseline就是基线. 注意:倒数第二根才是基线(base ...
- Apache的主要目录和配置文件详解
一.Apache 主要配置文件注释Apache的主配置文件:/etc/httpd/conf/httpd.conf默认站点主目录:/var/www/html/Apache服务器的配置信息全部存储在主配置 ...
- d3js data joins深入理解
Data joins 给定一个数据数组和一个 D3 selection 我们就可以attach或者说是'join'数组中的每个数据到selection中的每个元素上. 这将使得我们的数据和可视化元素 ...
- CC150相关问题
18.9 动态计算中位数 利用两个堆:一个最大堆,存放小于中位数的值:一个最小堆,存放大于中位数的值. 则两个堆的堆顶即为数组中最中间的两个数. 在插入新元素的时候,我们只要维护两个堆, 使其堆中元素 ...
- C/C++面试问题分类大汇总 ZZ 【C++】
http://www.mianwww.com/html/2014/05/21208.html 指针和引用的区别 指针指向一块内存,它的内容是指向内存的地址:引用是某内存的别名 引用使用是无需解引用,指 ...
- 使用事务和SqlBulkCopy批量插入数据
SqlBulkCopy是.NET Framework 2.0新增的类,位于命名空间System.Data.SqlClient下,主要提供把其他数据源的数据有效批量的加载到SQL Server表中的功能 ...