iOS多线程:【GCD】】详尽总结

此篇文章只是自学照别人抄的

iOS多线程:『GCD』详尽总结 - 简书

1.GCD简介

什么是GCD

GCD是 Apple开发的一个多核编程的较新的解决方案。它主要用于优化应用程序以支持多核处理器以及其他堆成多处理系统。他是一个在线程池模式的基础上执行的并发任务。

为什么要用GCD?

GCD 可用于多核的并行运算

GCD会自动利用更多的CPU内核(比如双核、四核)

GCD会自动管理县城的生命周期(创建线程、调度任务、销毁线程)

程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

2.GCD任务和队列

学习GCD之前先来了解GCD中两个核心概念:任务和队列。

任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码。在GCD中是放在Block中的。执行任务有两种方式:同步执行(sync)和异步执行(async)。两这的主要区别是:时都等待队列的任务执行结束,以及是否具备开创新线程的能力

同步执行(sync):

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

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

异步执行(async):

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

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

队列:(Dispatch Q)这里的队列指执行任务的等待队列,即用来存放任务的队列。队列是一种特殊的线性表,采用FIFO的原则即新任务总是被插入队尾。

在GCD中有两种队列:串行队列和并发队列。两者都一样

串行队列:每次只有一个任务被执行

并行队列:可以让多个任务(同时)执行。可以开启多个线程但是根据任务类型来判断

队列:就是任务执行的地方。是栈,为什么是栈,因为栈符合先进先出原则,可以控制任务执行顺序

GCD 的使用步骤

只需要两步

1创建一个队列

2追加任务到队列里

队列的创建方法

可以使用 dispatch_queue_create 来创建队列,需要传入两个参数,第一个参数是队列的唯一标识,用于我们方便Debug,可为空。第二个参数是用来识别串行队列还是并行队列,DISPATCH_QUEUE_SERIAL 标示串行队列DISPATCH_QUEUE_CONCURRENT表示并发队列

对于串行队列GCD提供了一个特殊的并行队列DISPATCH_GET_MAIN_QUEUE

对于并发队列GCD默认提供了全局并发队列DISPATCH_GET_GOLOBAL_QUEUE

他有两个参数第一个参数标示队列优先级 , 第二个参数暂时不用

任务的创建方法

同步任务的创建

dispatch_sync(queue, cal)

异步任务的创建

dispatch_async(queue,cal)

接下来是组合网上有很多我直接说结果

1同步任务

2异步任务

A串行队列

B并行队列

C主队列

1+A任务不会创建新的线程

1+B任务不会创建新的线程

1+C任务在主队列执行 死锁

2+A任务会创建线程但串行执行

2+B任务会创建线程

2+C不会创建线程在主队列执行

线程间通信

dispatch_get_main_queue

栅栏方法

dispatch_barrier_async

我们有时需要异步执行两组操作,而且第一组操作执行完之后,才能开始执行第二组操作。这样我们就需要一个相当于栅栏一样的一个方法将两组异步执行的操作组给分割起来,当然这里的操作组里可以包含一个或多个任务。这就需要用到dispatch_barrier_async方法在两个操作组间形成栅栏。

dispatch_barrier_async函数会等待前边追加到并发队列中的任务全部执行完毕之后,再将指定的任务追加到该异步队列中。然后在dispatch_barrier_async函数追加的任务执行完毕之后,异步队列才恢复为一般动作,接着追加任务到该异步队列并开始执行。具体如下图所示:

GCD延时执行方法

dispatch_after

我们经常会遇到这样的需求:在指定时间(例如3秒)之后执行某个任务。可以用 GCD 的dispatch_after函数来实现。

需要注意的是:dispatch_after函数并不是在指定时间之后才开始执行处理,而是在指定时间之后将任务追加到主队列中。严格来说,这个时间并不是绝对准确的,但想要大致延迟执行任务,dispatch_after函数是很有效的。

一次性代码

dispatch

我们在创建单例、或者有整个程序运行过程中只执行一次的代码时,我们就用到了 GCD 的 dispatch_once 函数。使用

dispatch_once 函数能保证某段代码在程序运行过程中只被执行1次,并且即使在多线程的环境下,dispatch_once也可以保证线程安全。

GCD 快速迭代方法

dispatch_apply

通常我们会用 for 循环遍历,但是 GCD 给我们提供了快速迭代的函数dispatch_apply。dispatch_apply按照指定的次数将指定的任务追加到指定的队列中,并等待全部队列执行结束。

如果是在串行队列中使用dispatch_apply,那么就和 for 循环一样,按顺序同步执行。可这样就体现不出快速迭代的意义了。

我们可以利用并发队列进行异步执行。比如说遍历 0~5 这6个数字,for 循环的做法是每次取出一个元素,逐个遍历。dispatch_apply可以 在多个线程中同时(异步)遍历多个数字。

还有一点,无论是在串行队列,还是异步队列中,dispatch_apply 都会等待全部任务执行完毕,这点就像是同步操作,也像是队列组中的dispatch_group_wait方法。

GCD 队列组

dispatch_group

有时候我们会有这样的需求:分别异步执行2个耗时任务,然后当2个耗时任务都执行完毕后再回到主线程执行任务。这时候我们可以用到 GCD 的队列组。

调用队列组的dispatch_group_async先把任务放到队列中,然后将队列放入队列组中。或者使用队列组的dispatch_group_enter、dispatch_group_leave组合 来实现

dispatch_group_async。

调用队列组的dispatch_group_notify回到指定线程执行任务。或者使用dispatch_group_wait回到当前线程继续向下执行(会阻塞当前线程)。

6.5.1 dispatch_group_notify

GCD信号量

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 本文首发于我的个人博客:「程序员充电站」[https://itcharge.cn]文章链接:「传送门」[https...
    ITCharge阅读 344,823评论 308 1,921
  • GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行。gcd中...
    MaybeLove00阅读 837评论 0 0
  • 这本书不是鸡汤成功学,从根本上说时间不属于任何一个人,每个人都需要始终按自己的节奏一直向前,将心比心,你怎么对待时...
    芷荣说阅读 284评论 0 0
  • 在爱情里,我们多想用一句:“你好!”作为开始。然后用一句:“再见!”做结尾。 貌似每一种离开我们都想潇洒的不留痕迹...
    梨子墨阅读 372评论 2 1
  • 家长会主要内容: 1、孩子的学习问题不在于知识的难度或是基础差,归根结底在于孩子的习惯问题和态度问题,没有解决这个...
    峡溪飞瀑阅读 2,158评论 0 0