跳过正文

高性能多线程gcd

·4 分钟
目录

前言
#

gcd 全名字是全局任务分发,线程管理的一种方式。GCD 更加趋近于底层性能较高。与gcd 相关的概念有,队列,队列组,同步异步函数。

队列
#

其中管理任务的是队列,包括串行队列,并行队列。

  • 系统提供了全局队列

    (并行队列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  • 系统提供了主队列

    (串行队列dispatch_get_main_queue())。

队列的不同指的是任务的分发不同,并行队列 一次下发多个任务,串行队列是一次下发一个任务。

同步和异步
#

同步与异步是指任务执行是否需要等待其他任务执行完返回数据。同步是需要等待的,异步是不需要等待的。

执行顺序(dispatch)
#

使用同步函数(必须等到 block 执行完)与异步函数(不必等 block 执行完),来决定任务的执行顺序。同步用于阻塞当前线程。

同步与异步 在执行的时候都是立马去执行,异步同步是一个开线程的能力而已 ,队列没有开线程的能力

同步执行串行队列
#

不开线程,等 blcok 任务执行完。会有阻塞当前线程的发生。(不开线程) 创建执行

AXu1j2

注意:串行队列异步执行有开线程的能力

异步执行并行队列
#

开线程不等待当前任务执行完返回数据,就可以执行接下来的任务。接下来的任务在在另外的线程执行。(开线程)

je6SrH

注意: 并行队列同步不开线程

队列与线程
#

  • 防止在串行队列中使用同步操作,会造成死锁。

    同步操作执行完才会返回。容易出现相互等待的情况。 例如:主线程执行同步操作会出现死锁。

死锁例子

8zU9w9

队列组与队列,队列完成通知
#

可解决多个如 ABC 任务(不分先后)执行后执行 D 任务。注意 ABC 开始执行是同步任务,在 D 之前这个用队列组没有问题,如果 ABC 是异步的话使用就会出现问题。

任务中还嵌套了异步任务,线程组不会管这个嵌套异步任务是否执行完成,调用了这个任务就 OK 了,因为是异步的我就不会等你执行完成就继续下一步了,一旦线程组第一层的任务都执行完成了就会调用通知。如果将异步换成同步的,就比需要等待嵌套任务执行完成才回去通知。

ABC 同步任务 d 在 abc 执行后执行

zw3Ko7
如果是异步分发同步任务 ABC(等同步执行完)执行 D,可以使用 GCD group 与 groupnotify。或者 NSBlockOperation 依赖解决。以及栅栏函数 dispatch_barrier(a)sync。

NSBlockOperation 依赖
#

isuPHV

dispatch*barrier_async(栅栏函数)
#

OzlGbN
dispatch_barrier*(a)sync 其中需要在新并行队列执行,异步栅栏函数或者同步栅栏函数就定了在执行栅栏函数内 block 是否要等待结果。参考

在同步栅栏时栅栏函数在主线程中执行,而异步栅栏中开辟了子线程栅栏函数在子线程中执行

例如图片下载 1,2,3,4 四个图片下载完在显示。上面使用都会无效。就要使用下面的结合信号量完成。

dispatch_semaphore(信号量)
#

信号常用的就是三个函数

OwRtIU
ABC 三个任务改成异步任务(如 AFN 网络请求)、全部回调成功后进行数据整合。
bhFhhv
使用 dispatch_semaphore_wait 将 blcok 的异步变为同步,只有 dispatch_semaphore_wait 执行完,才能算 group 的任务执行完。同时信号量也可以实现锁的功能,这个可在 SDWebImageManager 中看到。

dispatch_group_enter 和 dispatch_group_leave(任务组)
#

FIY3cU
利用了 dispatch_group_enter 与 dispatch_group_leave 成对出现来完成同步功能,然后发 group 通知。

任务整合总结
#

等待资源完成,在执行。

  • 异步并发执行同步任务后整合,

    使用 dispatch_group,以及通知,dispatch_barrier 和 NSOperation 的依赖

  • 异步并发执行异步任务后整合,

    可以用 dispatch_group+semaphore 初始化信号为 0,执行完一个异步通过 singnal 释放一个 wait 任务。

    例子如:多个任务网络请求,NSOperation 我感觉无法实现多网络任务执行完之后再最终统一执行某一个人任务。这个时候只有用 dispatch_group + semaphore 来实现。 或者用 disaptch_group_enter 和 dispatch_group_leave

dispatch_after 是任务追加函数,

dispatch_group_wait 超时判断函数。

总结
#

  • 代码执行时,资源的合理利用。任务分发机制(队列),任务的执行机制(异步函数同步函数)。
  • 并发编程中,一般会面对这样的三个问题:竞态条件、优先倒置、死锁问题。

使用 tip
#

gcd 队列,异步同步,信号量,锁,栅栏函数,一次性代码,延迟执行,定时器。

参考
#

https://blog.csdn.net/Deft_MKJing/article/details/51518556 https://www.jianshu.com/p/51fd1362249e