多线程-gcd

GCD简介(Grand Central Dispatch)

GCD是从ios4开始引入的新一代多线程编程技术

GCD需要用到一个系统库lib dispatch,lib dispatch是苹果的一个开发库,我们在使用时不需要导入这个库 因为系统层也在用这个库 所以这个库不导入它也会被加载进来

使用GCD开发者只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并有计划的执行任务,ios的内核会基于DIspatch Queue中的任务数量、CPU核数和CPU负荷等当前的系统状态来决定创建多少个线程和并发执行多少个任务

一、Dispatch Queue(调度队列)

使用GCD进行编程,开发者要做的只是定义想要执行的任务并追加到适当的Dispatch Queue中。调度队列中的任务按照FIFO(先入先出)的顺序进行处理,也就是先进入的任务现行处理

二、调度队列分为串行和并发两种

串行VS并发

串行:要求等待正在执行的任务完成,再执行下一个,也就是说只会创建一个线程来执行任务

并发:队列中后面的任务可以不必等待正在执行的任务完成就可以执行,也就是同时可以执行多个任务,也就是说会创建多个线程同时执行多个任务

1、串行队列

创建一个队列会开辟一个分线程,添加到串行队列中的任务在新线程中会按照添加的顺兴执行。串行队列经常处理一些需要顺序访问的任务。创建多个串行队列,多个串行队列间是并行的。

创建串行队列代码如下

/**

*  @author沈超, 16-07-15 14:07:33

*

*创建串行队列,添加到此队列的任务回一个挨着一个执行此队列会开辟一条线程执行任务

*

*  @param "com.cmcc.serialQueue"唯一标识符,一般域名反写+队列名,用于调试,崩溃报告中查看

*  @param NULL指定创建queue的类型,NULL或DISPATCH_QUEUE_SERIAL表示串行队列

*

*  @return <#return value description#>

*/

dispatch_queue_tserial_Queue=dispatch_queue_create("com.cmcc.serialQueue",NULL);/**

*  @author沈超, 16-07-15 14:07:10

*

*创建并发队列,添加到此队列的任务会并发执行,此队列会创建多个线程执行任务

*

*  @param "com.cmcc.concurrent_queue"唯一标识符,一般域名反写+队列名,用于调试,崩溃报告中查看

*  @param DISPATCH_QUEUE_CONCURRENT指定创建queue的类型,DISPATCH_QUEUE_SERIAL表示并发队列

*

*  @return <#return value description#>

*/

dispatch_queue_tconcurrent_queue=dispatch_queue_create("com.cmcc.concurrent_queue",DISPATCH_QUEUE_CONCURRENT);

三、系统提供队列全局队列和主队列

①全局队列

全局队列是一个在全局都可以获取的并发队列,而是只需要获取全局队列使用即可。全局队列有四种,即4个优先级,分别是high、default、low、background

获取全局队列的代码如下

dispatch_queue_t dispatch_global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

②主队列

主队列是一个在全局都可以获取的串行调度队列,该队列中的任务都是在主线程中执行的。因为是在主线程中执行,所以一般会将用户界面更新等一些必须在主线程中执行的任务追加带主队列中。

获取主队列代码如下

dispatch_queue_tmain_queue =dispatch_get_main_queue();

队列类型

创建的串行队列

创建的并发队列

获取的全局队列

获取的主队列

四、dispatch_async 和 dispatch_sync

任务:定义想要执行的任务 使用block语法来完成

同步提交:dispatch_sync同步添加任务到队列中,它是等待任务完成之后再继续执行。

异步提交:dispatch_async异步添加任务到异步队列中,它不会做任何等待

注意:同步提交不管提交到哪个什么队列,不会开辟新线程,在当前线程中执行

特别注意:同步提交要慎重使用,尤其是在当前队列中同步提交任务到当前队列,会造成线程死锁

五、dispatch_group

如果想在dispatch_queue中所有的任务执行完成后再做某种操作,在串行队列中,可以把该操作放到最后一个任务执行完成后执行,但是在并行队列中怎么做呢,这就有了dispatch_group成组操作

创建一个group

使用dispatch_group_async向组中添加队列和任务

当并行队列中的任务执行完时,使用dispatch_group_notify执行block通知group中的任务执行完毕

六、dispatch_semaphore

dispatch_semaphore信号量记忆计数器的一种多线程同步机制,在多线个线程访问共有资源时候,会因为多线程的特性而引发数据出错的问题。

GCD中有3个信号量有关的操作:

dispatch_semaphore_create     信号量创建

dispatch_semaphore_wait         信号量等待 wait会阻塞线程并且检测信号量的值,直到信号量值大于0才会往下执行,

同时对信号量执行-1操作

dispatch_semaphore_signal     发送通知+1 如果信号量值小于0直接唤醒线程继续执行

场景1:并发队列中的两个操作 操作1完成后操作2才能开始(线程间通信)

场景2:控制并发队列中并发任务数量

七、dispatch_once

使用Dispatch_once函数实现单例中的线程同步

该函数参数1 dispatch_once用于检查代码块是否已经被调度的谓词(其实就是长整形,实际上作为BOOL使用) 加static使用静态变量 以保证只执行一次。

参数2 希望在程序的生命周期内仅调用一次的代码块(适用于单例)如果被多个线程同时调用,该函数会同步等待,直至代码块完成

优势:

1、线程安全

2、仅需要少量代码块实现单例

八、dispatch_barrier_async

在并发队列中,使用dispatch_barrier_async添加的任务,队列在执行此任务时,队列中的其他任务不会执行,执行完成后该队列回复原有执行状态,继续并发执行

当一系列的操作都需要依赖于某个操作时,使用dispatch_barrier_async

注意:使用用户创建的并发队列(在系统队列中阻塞无效,等价于dispatch_async)

九、Dispatch_apply

Dispatch_apply是Dispatch_sync和dispatch_group的关联API。

dispatch_apply函数值将指定次数的指定任务(block)添加到queue中(此处queue一般为并发队列)

dispatch_apply是同步函数,会阻塞当前线程直到所有循环中任务执行完成,这些任务在queue中的执行顺序是不确定的(要并发,要提高效率)

十、Dispatch_after&&dispatch_time

Tips:

并发VS并行

并发指的是同时执行了多个任务,在多个任务间切换,一般是指同一时间间隔同时执行了多个任务(一般指单核)

并行值的是同时执行多个任务,一般是指同一时刻同时执行了多少任务(一般指多核)

并行:(多核)

cpu1:任务part1

thread:_________________

cpu2:任务part2

thread:_________________

并发:(单核)

thread1—   —    —    —    —    —   —   —任务part1

thread2   —   —    —    —    —    —    —   —任务part2

并行要求并发,并发并不能保证并行(单核)

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

推荐阅读更多精彩内容