GCD详解

GCD(Grand Central Dispatch)是一套用于并发编程的API,提高程序性能和利用多核优势。它包括主要队列、全局队列和用户队列,提供同步、异步、并发和串行任务执行。GCD的特性包括自动调整线程数量,减少上下文切换,易于使用Block进行编程。了解GCD的四种术语:同步执行不开启新线程,异步执行可能开启新线程,并发执行多个任务,串行执行任务按顺序执行。使用GCD进行任务调度,如dispatch_async、dispatch_group等,可以实现复杂的并发控制和事件监听。
摘要由CSDN通过智能技术生成

什么是GCD?

Grand Central Dispatch或者GCD,是一套底层API,提供了一种新的方法来进行并发程序编写。使用GCD来提升程序性能以及发挥多核系统优势.

GCD的工作原理:

让程序平行的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务.

GCD提供了很多超越传统多线程编程的优势.

  • 简单易用,居于block的血统,导致它能极为简单的在不同代码作用域之间传递上下文,

  • 效率,它在很多地方比之专门创建消耗资源的线程更实用且快速,

  • 性能,GCD自动根据系统负载来增减线程数量.这就减少了上下文切换以及增加了计算效率.

GCD中有三种队列类型:

  • The main queue: 与主线程功能相同。实际上,提交至main queue的任务会在主线程中执行。main queue可以调用dispatch_get_main_queue()来获得。因为main queue是与主线程相关的,所以这是一个串行队列。
  • Global queues: 全局队列是并发队列,并由整个进程共享。进程中存在三个全局队列:高、中(默认)、低三个优先级队列。可以调用dispatch_get_global_queue函数传入优先级来访问队列。
  • 用户队列: 用户队列 (GCD并不这样称呼这种队列, 但是没有一个特定的名字来形容这种队列,所以我们称其为用户队列) 是用函数 dispatch_queue_create 创建的队列.

有4个术语比较容易混淆:同步、异步、并发、串行

同步和异步决定了要不要开启新的线程

  • 同步: 在当前线程中执行任务,不具备开启新线程的能力

  • 异步: 在新的线程中执行任务,具备开启新线程的能力

并发和串行决定了任务的执行方式

  • 并发: 多个任务并发(同时)执行

  • 串行: 一个任务执行完毕后,再执行下一个任务

尽管GCD是纯c语言的,但它被组建成面向对象的风格。GCD对象被称为dispatch object。Dispatch object像Cocoa对象一样是引用计数的。

dispatch_resume() 继续执行线程

dispatch_suspend() 挂起线程 中断线程

dispatch_sync() 同步添加操作。他是等待添加进队列里面的操作完成之后再继续执行。

dispatch_async () 异步添加进任务队列,它不会做任何等待

dispatch_get_main_queue() 主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行

dispatch_queue_create() 创建一个队列

第一个参数是一个标签,这纯是为了debug。Apple建议我们使用倒置域名来命名队列,比如“com.dreamingwish.subsystem.task”。这些名字会在崩溃日志中被显示出来,也可以被调试器调用这在调试中会很有用,所有尽量不要重名了。
第二个参数 设置你的队列是否串行或并行.一般我是设置NULL,它是串行

DISPATCH_QUEUE_SERIAL  |  DISPATCH_QUEUE_CONCURREN

 

dispatch_get_global_queue() 全局并发队列,并由整个进程共享, 可设定优先级来选择高、中、低, 后台优先级队列。说明:全局并发队列的优先级

    #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高 
    #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中) 
    #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低 
    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台

dispatch_group_create()创建一个调度任务组 它可以将对象关联

dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block);

group 提交到的任务组,这个任务组的对象会一直持续到任务组执行完毕
queue 提交到的队列,任务组里不同任务的队列可以不同
block 提交的任务

func dispatchgroup_notify( group: dispatchgroup_t!, queue: dispatch_queue_t!,_block: dispatch_block_t!)

group监听的任务组
queue 执行完毕的这个闭包所在的队列
block执行完毕所响应的任务 

dispatch_group_wait 设置等待时间,在等待时间结束后,如果还没有执行完任务组,则返回。返回0代表执行成功,非0则执行失败

dispatchgroup_enter/dispatch_group_leavefunc dispatch_group_enter( group: dispatchgroup_t!)func dispatch_group_leave( group: dispatch_group_t!)

这两个方法显示的讲任务组中的任务未执行完毕的任务数目加减1,这种方式用在不使用dispatch_group_async来提交任务

注意:这两个函数要配合使用,有enter要有leave,这样才能保证功能完整实现。也可以用这对函数来让一个闭包关联多个Groupdispatch_group_notify 用来监听任务组事件的执行完毕

void dispatch_apply(size_t iterations, dispatch_queue_t queue,void (^block)(size_t)) 这个函数调用单一block多次,并平行运算,然后等待所有运算结束,作用是把指定次数指定的block添加到queue中

第一个参数是迭代次数
第二个是所在的队列
第三个是当前索引

看完上面的介绍,下面来简单的使用GCD吧.

一个在异步执行的串行队列,如若想并发执行将DISPATCH_QUEUE_SERIAL换成DISPATCH_QUEUE_CONCURRENT即可.

串行队列只会创建一条异步线程,并发队列将会创建多个线程

    array = @[@"guo",@"bin",@"ai",@"chun",@"yan"];   
    dispatch_queue_t serialQueue = dispatch_queue_create("BIn.text", DISPATCH_QUEUE_SERIAL);   
 
    for (id obj in array) {   
       dispatch_async(serialQueue, ^{   
           for (int i = 1; i <= 100; i++) {   
                NSLog(@"%@ = %d",obj,i);   
           } 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值