GCD(Grand Center Dispatch)使用详解

本文详细介绍了Apple的GCD(Grand Central Dispatch),包括GCD的基础概念、公开现成队列(主队列、四种通用调度队列)与自定义队列(串行队列和并发队列)。重点讲解了队列优先级设置、dispatch_groups的使用、dispatch_after、dispatch_barrier_async的应用,以及如何避免死锁。通过各种示例,阐述了GCD在多线程编程中的实践与策略。
摘要由CSDN通过智能技术生成

一、GCD简介
GCD是苹果公司推出的基于多核CPU多线程技术,GCD属于系统级的线程管理,在Dispatch queue中执行需要执行的任务性能非常高。GCD这块已经开源,地址是 http://libdispatch.macosforge.org

二、按获取方式分类队列
dispatch queue队列就是执行任务的队列,由于遵循 First in First out(先进先出),所以又称为 FIFO队列。队列有一个基本概念是串行队列和并发队列。

GCD中按获取方式划分:
1. 公开现成队列
公开现成队列是直接可以获取,不需要创建,而且开发者也不能够创建该队列。
公开现成队列又分为5种,分别是主队列、四种通用调度队列,主队列就是运行在主线程上的队列,四种通用调度队列分别如下:
QOS_CLASS_USER_INTERACTIVE: user interactive等级表示任务需要被立即执行提供好的体验,用来更新UI,响应事件等。这个等级最好保持小规模。

QOS_CLASS_USER_INITIATED:user initiated等级表示任务由用户发起异步执行。适用场景是需要及时得到结果同时又可以继续交互的时候。

QOS_CLASS_UTILITY:utility等级表示需要长时间运行的任务,伴有用户可见进度指示器。经常会用来做计算,I/O,网络,持续的数据填充等任务。这个任务需要节能。

QOS_CLASS_BACKGROUND:background等级表示用户不会察觉的任务,使用它来处理预加载,或者不需要用户交互和对时间不敏感的任务。

示例: 后台加载显示图片:

func loadRemoteImage(URLString: String){
 dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0))  {
    let image = self.downloadImageFromURL(URLString)
    dispatch_async(dispatch_get_main_queue()) { // 图片完成,把一个闭包提交到主线程上更新UI
        self.easeInNewImage(image)    // 更新 UI
           }
        }
    }

1.1 运行到主线程上的main queue

dispatch_get_main_queue()

1.2 High Priority Queue

dispatch_get_global_queue(Int(QOS_CLASS_USER_INTERACTIVE.rawValue), 0)

1.3 Default Priority Queue

dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)

1.4 Low Priority Queue

dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.rawValue), 0)

1.5 Background Priority Queue(用于I / O)

dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.rawValue), 0)

可以使用下面的方法简化QoS等级参数的写法:

var GlobalMainQueue: dispatch_queue_t {
     return dispatch_get_main_queue()
}
var GlobalUserInteractiveQueue: dispatch_queue_t {
     return dispatch_get_global_queue(Int(QOS_CLASS_USER_INTERACTIVE.value), 0)
}
var GlobalUserInitiatedQueue: dispatch_queue_t {
     return dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)
}
var GlobalUtilityQueue: dispatch_queue_t {
     return dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)
}
var GlobalBackgroundQueue: dispatch_queue_t {
     return dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0)
}

//使用起来就是这样,易读而且容易看出在使用哪个队列
dispatch_async(GlobalUserInitiatedQueue) {
     let overlayImage = self.faceOverlayImageFromImage(self.image)
     dispatch_async(GlobalMainQueue) {
          self.fadeInNewImage(overlayImage)
     }
}

2 . 自定义队列。
自定义队列有两种类型:串行队列、并发队列

串行队列:底层维护了一个线程池,线程池中维护了一个线程,提交任务到该类队列上时,只能提交到一个线程上,不能实现多线程编程;

dispatch_queue_create("com.manchelle.gcddemo.serialqueue", DISPATCH_QUEUE_SERIAL)

并发队列:底层维护了一个线程池,线程池中维护了多个线程,提交任务到该类队列上时,任务由系统自动配置多个线程上,能实现多线程编程。

dispatch_queue_create("com.manchelle.gcddemo.concurrent", DISPATCH_QUEUE_CONCURRENT)

五、自定义队列优先级设置方式
自定义队列优先级:可以通过dispatch_queue_attr_make_with_qos_class或者dispatch_set_target_queue方法设置队列优先级

/**  dipatch_queue_attr_make_with_qos_class 方式 
*    QOS_CLASS_USER_INITIATED
*
*    QOS_CLASS_USER_INTERACTIVE
*   
*    QOS_CLASS_UTILITY
*   
*    QOS_CLASS_BACKGROUND
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值