了解GCD

2023-05-16

目录

一、GCD简介

二、GCD好处

三、GCD任务和队列

1、任务

同步执行(sync):

异步执行(async):

2、队列

串行队列(Serial Dispatch Queue):

并发队列(Concurrent Dispatch Queue):

四、GCD的使用步骤

1、队列的创建方法/获取方法

2、 任务的创建方法

五、GCD的基本使用

1、同步执行 + 并发队列

2、异步执行 + 并发队列

3、同步执行 + 串行队列

4、异步执行 + 串行队列

5、主队列

5.1、主队列 + 异步任务

5.2、主队列 + 同步任务

六、总结

本文章为作者学习文档,如有转载,侵权问题,请自主联系作者,谢谢。

一、GCD简介

Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用

二、GCD好处

  • GCD可用于多核并发运算。
  • GCD会自动利用更多的CPU内核。
  • GCD会自动管理线程的生命周期(创建线程,调度任务,销毁线程)。
  • 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码。

三、GCD任务和队列

1、任务

任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码。

执行任务的方式有两种:同步执行(sync)和异步执行(async)。

两者的主要区别是:是否等待队列的任务执行结束,以及是否具备开启新线程的能力。

同步执行(sync):

同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。

只能在当前线程中执行任务,不具备开启新线程的能力。

异步执行(async):

异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务。

可以在新的线程中执行任务,具备开启新线程的能力。

注意: 异步执行(async) 虽然具有开启新线程的能力,但是并不一定开启新线程。这跟任务所指定的队列类型有关。

2、队列

队列:这里的队列指执行任务的等待队列,即用来存放任务的队列。队列是一种特殊的线性表,采用FIFO(先进先出)的原则。

GCD中有两种队列:串行队列和并行队列。两者都符合先进先出的原则。

两者的主要区别是:执行顺序不同,以及开启线程数不用。

串行队列(Serial Dispatch Queue):

每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)

并发队列(Concurrent Dispatch Queue):

可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)

注意: 并发队列 的并发功能只有在异步(dispatch_async)函数下才有效

四、GCD的使用步骤

GCD 的使用步骤其实很简单,只有两步。

  • 创建一个队列(串行队列或并发队列)
  • 将任务追加到任务的等待队列中,然后系统就会根据任务类型执行任务(同步执行或异步执行)

1、队列的创建方法/获取方法

  • 可以使用dispatch_queue_create来创建队列,需要传入两个参数,第一个参数表示队列的唯一标识符,用于 DEBUG,可为空,Dispatch Queue 的名称推荐使用应用程序 ID 这种逆序全程域名;第二个参数用来识别是串行队列还是并发队列。DISPATCH_QUEUE_SERIAL 表示串行队列,DISPATCH_QUEUE_CONCURRENT 表示并发队列。
// 串行队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
// 并发队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
  • 对于串行队列,GCD 提供了的一种特殊的串行队列:主队列(Main Dispatch Queue) 。

  • 所有放在主队列中的任务,都会放到主线程中执行。

  • 可使用dispatch_get_main_queue()获得主队列。

// 主队列的获取方法
dispatch_queue_t queue = dispatch_get_main_queue();
  • 对于并发队列,GCD 默认提供了全局并发队列(Global Dispatch Queue)。
  • 可以使用dispatch_get_global_queue来获取。需要传入两个参数。第一个参数表示队列优先级,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二个参数暂时没用,用0即可。
// 全局并发队列的获取方法
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

2、 任务的创建方法

GCD 提供了同步执行任务的创建方法dispatch_sync和异步执行任务创建方法dispatch_async。

// 同步执行任务创建方法
dispatch_sync(queue, ^{
    // 这里放同步执行任务代码
});
// 异步执行任务创建方法
dispatch_async(queue, ^{
    // 这里放异步执行任务代码
}); 

五、GCD的基本使用

区别并发队列串行队列主队列
同步(sync)没有开启新线程,串行执行任务没有开启新线程,串行执行任务没有开启新线程,串行执行任务
异步(async)有开启新线程,并发执行任务有开启新线程(1条),串行执行任务没有开启新线程,串行执行任务

1、同步执行 + 并发队列

代码如下:

 

结果如下: 

 

根据结果可知:在当前线程中执行任务,不会开启新线程,执行完一个任务,在执行下一个任务。

2、异步执行 + 并发队列

代码如下:

 

 结果如下:

 

根据结果可以得出:除了当前的主线程,系统又开启了3个线程,并且任务是交替/同时执行的。

3、同步执行 + 串行队列

代码如下:

 结果如下:

 

根据结果可以得出:所有任务都是在当前线程中执行,并且没有开启新的线程,任务是按照顺序执行的,因为是串行队列,所以每次只有一个任务执行,一个认为完成,然后下一个任务开始。

4、异步执行 + 串行队列

代码如下:

结果如下:

 

根据结果可以得出:会开启新的线程,但是因为任务是串行的,所以执行完一个任务,在执行下一个任务。

5、主队列

主队列:是专门负责调度主线程的任务,没有办法开辟新的线程。所以,在主队列下的任务不管是异步任务还是同步任务都不会开辟线程,任务只会在主线程顺利执行。

5.1、主队列 + 异步任务

代码如下:

 结果如下:

根据结果可以得出:主队列中放入异步任务,不是马上执行,而是等到主队列中的其他不是我们异步添加的任务执行完成之后,才会执行我们异步添加的任务。

 

5.2、主队列 + 同步任务

主队列 + 同步任务 在不同的线程中会出现不同的结果,当在主线程中调用,会出现死锁,而在其他的线程中则不会。

GCD

六、总结

线程和队列,异步同步函数的关系?

A、一个应用程序表示开启了一个线程。

B、一个进程至少有一个线程,即至少有一个主线程,也可以开启多条线程。

C、一个线程中可以有多个队列,每个队列中额可以执行多个任务。

D、在线程中执行任务的顺序可以是按顺序来执行,也可以用不按顺序来执行。即表现为串行和并行。

E、那异步和同步函数的作用在哪里?

并行和串行队列,与异步同步函数的排列组合有如下这些:

1)并行队列+异步函数:开启多条线程,不按顺序执行任务。

2)串行队列+异步函数:开启一条新线程,按顺序执行任务。

3)主队列+异步函数:不开启新的线程,按顺序执行任务。

4)并行队列+同步函数:不开启新的线程,按顺序执行任务。

5)串行队列+同步函数:不开启新的线程,按顺序执行任务。

6)主队列+同步函数:会出现死锁现象。原因:循环等待,主队列的东西要等主线程执行完,又不能开线程,所以下面的任务要等上面的任务执行完,然后就卡死了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解GCD 的相关文章

  • 莫比乌斯反演对gcd问题的优化

    题目 xff1a http bz cdqzoi com JudgeOnline problem php id 61 2818 题意 xff1a 给一个正整数 xff0c 其中 xff0c 求使得为质数的的个数 xff0c 分析 xff1a
  • BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】

    题目 Sheng bill有着惊人的心算能力 xff0c 甚至能用大脑计算出两个巨大的数的GCD xff08 最大公约 数 xff09 xff01 因此他经常和别人比 赛计算GCD 有一天Sheng bill很嚣张地找到了你 xff0c 并
  • 数论——GCD

    ZOJ Problem Set 3846 题意 xff1a 给 N 个数 xff0c 任取两个数Ai Aj xff0c 求出这两数的GCD xff0c 然后用GCD替换这两个数的值 直至这n个数的值都相等为止 xff0c 此时输出求GCD的
  • 证明,若gcd(n,i) == 1,那么gcd(n,n-i)==1

    证明 xff0c 若gcd n i 61 61 1 那么gcd n n i 61 61 1 解 xff1a 设gcd n i 61 61 1 gcd n n i 61 61 k 61 1 那么n与 n i 的最大公约数为k n k 61 6
  • 求解gcd最大公约数的两种算法

    文章目录 1 更相减损术2 辗转相除法3 两种算法的比较 1 更相减损术 即 xff1a 辗转相减法 是由我国古代 九章算术 提出的一种求解最大公约数 Grand Central Dispatch 的算法 代码示例 xff1a span c
  • 【题解】洛谷P2651 添加括号III(gcd 数学)

    看到是入门难度结果看了半天也不知道啥做法 kkk大神给出了答案 xff0c a1肯定在分子上 xff0c a2肯定在分母上 xff0c 如果我们想让这个式子更有可能化成整数 xff0c 那么a1 a3 a4 an都应该在分子上 xff0c
  • 证明:当gcd(a, b) = 1,则gcd(a + b, a) = 1

    假设 xff1a gcd a b 61 1 证明 xff1a gcd a 43 b b 61 1 反证法 xff1a 假设gcd a 43 b b 61 k 61 1 则 xff1a b 61 k r1 a 43 b 61 a 43 k r
  • 数学方法证明辗转相除法(欧几里得算法):gcd(a,b)=gcd(b,a%b)

    纯数学方法证明辗转相除法 xff08 欧几里得算法 xff09 xff1a gcd a b 61 gcd b a b 1 首先 设gcd a b 61 gcd b a b 61 d 2 构造k与c 得到a 61 kb 43 c 其中c 61
  • 更相减损法和辗转相除法(GCD)求最小公倍数和最大公约数

    更相减损法和辗转相除法 xff08 GCD xff09 求最小公倍数和最大公约数 标签 xff08 空格分隔 xff09 xff1a 算法 算法竞赛 这两种算法平时经常听到 xff0c 听起来也很装逼 xff0c 但是我老是忘了他们的原理
  • 基础算法题——奇怪的分式(避免小数运算)

    奇怪的分式 上小学的时候 小明经常自己发明新算法 一次 老师出的题目是 1 4 乘以 8 5 小明居然把分子拼接在一起 分母拼接在一起 答案是 18 45 参见图1 png 老师刚想批评他 转念一想 这个答案凑巧也对啊 真是见鬼 对于分子
  • gcd函数和lcm函数(c/c++)

    gcd函数和lcm函数 c c gcd函数简介 最大公因数 英语 highest common factor hcf 也称最大公约数 英语 greatest common divisor gcd 是数学词汇 指能够整除多个整数的最大正整数
  • iOS进阶_GCD(二.GCD串行队列&并发队列)

    GCD 核心概念 将任务添加到队列 指定任务执行的方法 任务 使用block封装 block 就是一个提前准备好的代码块 在需要的时候执行 队列 负责调度任务 串行队列 一个接一个的调度任务 并发队列 可以同时调度多个任务 任务执行函数 任
  • 最大公约数、最小公倍数、辗转相除法的求解和证明

    两个正整数的最大公约数 Greatest Common Divisor GCD 在计算机中通常使用辗转相除法计算 最小公倍数 Least Common Multiple LCM 可以使用GCD来计算 下面首先介绍GCD和LCM 然后介绍辗转
  • 3045 Lcm与Gcd构造

    已知 gcd a b n lcm a b m 求min a b 是多少 通过gcd的了解我们可以知道 两个数a k1 n以及b k2 n并且gcd k1 k2 1 ab n m m a b n ab k1 k2 n n 于是可以得到 m k
  • 扩展欧几里得算法

    扩展欧几里得算法是啥 那就要先知道什么是欧几里得算法 欧几里得算法 扩展欧几里得算法是欧几里得算法的推广 利用欧几里得算法的思想和递归求得贝祖等式a x b y gcd a b 不定方程中的一组x和y的解 原理如下 设a gt b 当b 0
  • 一个奇怪的GCD内存不释放的问题

    这个问题是我的同学提出来的 原帖在http bbs csdn net topics 390933411 大概是这样 pre class objc IBAction touchToCreateThread id sender int i 10
  • 最大公约数GCD

    输入2个正整数A B 求A与B的最大公约数 Input2个数A B 中间用空格隔开 1 lt A B lt 10 9 Output输出A与B的最大公约数 Sample Input 30 105 Sample Output 15 includ
  • 最大比例

    题目描述 解析 接下来就是求解k和p的过程 在这道题中很难使用欧几里得算法就求解最大公约数 因此尝试使用另一种方法 更相减损术 循环相减法 如果要使用欧几里得算法的话 就需要开一个非常复杂的根号 非常难算 代码 include
  • Two Divisors【GCD数论】

    You are given nn integers a1 a2 ana1 a2 an For each aiai find its two divisors d1 gt 1d1 gt 1 and d2 gt 1d2 gt 1 such th
  • iOS线程初探(四) GCD 和 NSOperation 小结

    参考资料 关于iOS多线程 看我就够了 GCD 在GCD中 有两个概念很重要 那就是任务和队列 任务 其实就是你需要做的事情 一个Block而已 任务有两种执行方式 同步执行和异步执行 同步执行 会阻塞当前线程 直至该任务执行完成后当前线程

随机推荐