GCD整理

基本的数据结构

GCD的类都是struct定义的。

  • 包括所有的父类的数据成员,都平铺重复的写在一个个的struct中。
  • 提高效率,避免引入继承机制带来的代码执行上的延迟.
  • 为了减少代码量和易读性,做了许多宏定义。

dispatch_object_t
GCD中类都继承自统一的基类dispatch_object_t。是一个联合union,作用和基类指针相似,所有的子类型都可以用dispatch_object_t统一表示。

_os_object_s
表示系统对象的基类_os_object_s

dispatch_continuation_s
向queue提交的任务,无论block还是function形式,最终都会被封装为dispatch_continuation_s。
保存block的上下文环境和block执行函数等。

dispatch_queue_s
GCD中的queue。

dispatch_queue_attr_s
GCD中的队列的属性与状态。

GCD线程概况

在GCD中一共有2个线程池管理着任务,一个是主线程池,另一个就是除了主线程任务的线程池。主线程池由序号1的队列管理,其他有序号2的队列进行管理。加上runloop运行的runloop队列,一共就有16个队列。

1号 main queue,2号 manager queue,3没有使用,4到11表示global queue,再往后就是用户自定义queue了。

application启动的时候就会初始化这些root队列的_dispatch_root_queues_init函数。

GCD用到的queue,无论是自己创建的,或是获取系统的main queue还是global queue,其最终都是落脚于GCD root queue中。可以在代码中的任意位置创建queue,但最终GCD管理的,就这(4到15)12个root queue,分别有不同的优先级和序列号。这种思路有点类似于命令模式,即分散创建,集中管理。

dispatch_queue_create
用户要创建一个queue的时候,需要指定target queue,即创建的queue最终是在哪个queue上执行的,这个target queue会取root queue之一。

调用dispatch_queue_create,GCD内部会调用_dispatch_queue_create_with_target, 它首先会根据我们创建的queue的属性:DISPATCH_QUEUE_SERIALDISPATCH_QUEUE_CONCURRENT,到root queue数组中取出一个对应的queue作为target queue。然后,会新建一个dispatch_queue_t对象,并设置其target queue,返回给用户。同时,在GCD内部,新建的queue还会被加入introspection queue列表中

dispatch_get_global_queue
首先将外部传入的queue优先级转换为GCD内部的优先级dispatch_qos_t qos。 然后,在调用_dispatch_get_root_queue 获取root queue中对应的queue。

dispatch_get_main_queue
main queue是由系统在main()方法调用前创建的。专门绑定到main thread上。而且,为了触发提交到main queue上的block,和其他queue不一样,main queue上的任务是依赖于main runloop触发的

application启动的时候就会初始化这些root队列的_dispatch_root_queues_init函数。

dispatch_sync
dispatch_sync直接调用的是dispatch_sync_f

装入到自定义的任务和方法都被封装成 dispatch_continuation_t 结构体后,扔到其挂靠的root队列里去,所以自己创建的队列只是一个代理人身份,真正的管理人是其对应的root队列。
最后通过_dispatch_continuation_pop方法把事件压入队列执行
_dispatch_sync_wait 检测死锁的函数

dispatch_async
无论“线程标示”是什么类型的queue,GCD首先会将传入队列和方法打包成dispatch_continuation_t类型,然后调用方法_dispatch_continuation_async

dispatch_async底层运用了线程池,会在和当前线程不同的线程上处理任务。

串行任务
将block打包成dispatch_continuation_t, 然后把dispatch_queue_t通过_dispatch_continuation_push入队到响应的root queue中,root queue中的线程池中的线程会被唤醒,执行线程函数_dispatch_worker_thread3,root queue会被倾倒,执行queue中的任务。

并行任务
将block打包成dispatch_continuation_t,然后并行队列会走 _dispatch_async_f2
首先会被替换为对应的root queue,将自定义dispatch_queue_t入队。如果是第一次入队,则会去激活所有的root queue,即创建XUN 内核支持的workqueue(升级版线程池,会自动判断是否需要创建新的线程),然后将workqueue的工作函数设置为_dispatch_worker_thread3。_dispatch_worker_thread3 会调用_dispatch_root_queue_drain,将root queue进行清空,它会清空所有提交到当前root queue中的dispatch_queue_t,并执行它们的dq任务。

dispatch_once
#define dispatch_once _dispatch_once 是一个宏定义
当单例方法执行完毕,GCD会将onceToken置为~0。如果再次调用单例方法,GCD会发现onceToken已经使用过,就直接返回了,并且用原子操作防止多线程下多次调用。

dispatch_group
dispatch_group的相关函数是通过dispatch_semaphore控制的

dispatch_group_create
创建一个dispatch_group_t类型实例并返回。实际是创建了一个信号量 通过_dispatch_semaphore_class_init控制的

dispatch_group_wait
内部是调用的_dispatch_group_wait_slow

dispatch_semaphore_create
调用_dispatch_semaphore_class_init

dispatch_semaphore_wait
调用_dispatch_group_wait_slow

dispatch_barrier_async
dispatch_async直接把任务扔到root队列,而dispatch_barrier_async是把任务在到自定义的队列。

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