GCD是Apple开发的一个多核编程的解决方法,是一个代替NSThread, NSOprationQueue, NSInvocationOperation等技术的一个高效、强大、底层的技术。
GCD支持同步或异步任务处理,串行或并行的处理队列,非系统调用的信号量机制,进程,文件或网络的监听任务等。
GCD 是一项跨时代的技术,纯C语言、但又有面向对象思想、基于Block,用难以置信的简洁方法实现了复杂繁琐的多线程编程。
优点:
易用:GCD比thread更简单易用。基于block的特性,简单的实现不同代码作用域传递上下文。
效率:GCD实现功能时轻量、优雅,在很多地方比专门创建消耗资源的线程更实用且快速。
安全:无需枷锁或其他同步机制。
DISPATCH QUEUE
Dispatch Queue是什么?是执行处理的等待队列。通过dispatch_async等函数,按照先进先出(FIFO)顺序追加到Queue中处理。
执行处理时,存在两种Dispatch Queue:
1、 Serial Dispatch Queueà等待现在正在执行的任务处理结束(串行)
一个线程同时执行一个任务, 可以避免数据竞争的问题
可以生成多个Serial Dispatch Queue, 各个Serial DispatchQueue并行执行
2、 Concurrent Dispatch Queue à不等待现在正在执行的任务处理结束
多个线程同时执行多个任务,效率高。CPU的核数和CPU负荷决定并发执行的个数。
GCD使用
1、 dispatch_queue_create(@"hehe",DISPATCH_QUEUE_SERIAL)创建一个队列
2、 dispatch_get_main_queue 得到主线程队列
3、 dispatch_get_global_queue 是所有应用程序都能够使用的ConcurrentDispatch Queue(4个优先级)
4、 dispatch_async
async 、asynchronous、异步。将指定的Block块异步追加到指定的DispatchQueue中。
5、 dispatch_sync
追加Block前,dispatch_sync函数会一直等待,前面的所有任务完成后才能执行追加的Block。容易产生死锁:主线程里执行往主线程队列里添加任务的
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"test");
});
6、 dispatch_suspend、dispatch_resume
这两个函数是异步的,且只在不同的blocks之间生效,对正在执行的任务没有影响。dispatch_suspend 后,Dispatch Queue中尚未执行的任务停止执行。dispatch_resume使这些任务继续执行
调用dispatch_suspend使suspension reference count 加1,使用dispatch_resume函数减1。当referencount 大于0 时,queue保持挂起状态。
7、 dispatch_once 一次执行
dispatch_once不管是否多线程,代码块只执行一次。实现单例,安全、简洁、方便
7、 dispatch_after
延时调用。在指定的时间后把任务追加到DispatchQueue里面。提交到dispatch_after中的代码,不能(直接)取消。
GCD高级用法
1、dispatch_group_async
多个任务都结束后的一个全部结束的处理;用来监视一组block对象的完成。可以同步或异步监视。
dispatch_group_notify 不阻塞当前线程,所有任务执行结束后汇总
dispatch_group_wait 阻塞当前线程,等待直到所有任务执行结束。
2、 dispatch_apply
dispatch_apply 函数是dispatch_sync和DispatchGroup的关联API。
按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束。
dispatch_apply等待处理结束才添加,推荐在dispatch_async中异步执行。
dispatch_apply 可以实现高性能的循环迭代
NSArray *arr = @[@0, @1, @2, @3, @4, @5];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_apply([arrcount], dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%@", arr[index]);
});
});
3、 dispatch_barrier_async
使用Concurrent DispatchQueue 和dispatch_barrier_async函数可以实现数据库访问和文件访问。
4、 dispatch semaphore
当并行执行的任务更新数据时,会产生数据不一样的情况,有时候还会异常结束。
dispatchsemaphore 是持有计数的信号,使用技术来实现该信号功能。技术为0时等待,技术大于等于1时,减去1而不等待。