现代系统通常提供异步接口,允许应用向系统提交请求,然后在系统处理请求时应用可以继续处理自己的事情。Grand Central Dispatch正是基于这个基本行为而设计,允许你提交请求,并通过block和dispatch queue报告结果。
Dispatch Queue
Dispatch Queue是GCD中很重要的一部分,它是负责执行处理的队列,它的内部主要由三部分构成:
1、一个管理追加block的C语言实现的FIFO的队列;
2、处理信号量的原子操作;
3、用于管理线程的C语言实现的一些容器。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"我的操作");
});
dispatch queue 通过结构体和链表,被实现成 FIFO 的队列。FIFO 的队列用来管理通过 dispatch_async 等函数追加的 Block。Block 并不是直接加入 FIFO 的队列,而是先加入 Dispatch Continuation 这一个 dispatch_continuation_t类型结构体中,然后再加入 FIFO的队列,构造体包含了这个block还有一些上下文信息,例如block所属的dispatch group等等。
Dispatch Queue执行过程是怎么的呢?
workqueue
- 工作队列,是一个用于创建内核线程的接口,通过它创建的内核线程来执行内核其他模块排列到队列里的工作。不同优先级的dispatch queue对应着对应优先级的workqueue。GCD初始化的时候,使用pthread_workqueue_create_np创建pthread_workqueue
执行过程
-
当在 Global Dispatch Queue 中执行Block时,libdispatch 从 Global Dispatch Queue 自身的 FIFO 队列取出 Dispatch Continuation,调用pthread_workqueue_additem_np 函数。将该 Global Dispatch Queue 本身、符合其优先级的 workqueue 信息以及执行Dispatch Continuation的回调函数等传递给参数
-
调用该函数后,会通知对应的workqueue增加执行项目,XNU内核生成线程,线程执行pthread_workqueue函数执行block
Dispatch Sources
- dispatch source是一个监视某些类型事件的对象。当这些事件发生时,它自动将一个block放入一个dispatch queue的执行例程中。
dispatch source是基础数据类型,协调特定底层系统事件的处理。Grand Central Dispatch支持以下dispatch source:
-
Timer dispatch source:定期产生通知
-
Signal dispatch source:UNIX信号到达时产生通知
-
Descriptor dispatch source:各种文件和socket操作的通知
-
数据可读
-
数据可写
-
文件在文件系统中被删除、移动、重命名
-
文件元数据信息改变
-
Process dispatch source:进程相关的事件通知
-
当进程退出时
-
当进程发起fork或exec等调用
-
信号被递送到进程
-
Mach port dispatch source:Mach相关事件的通知
-
Custom dispatch source:你自己定义并自己触发
Dispatch source替代了异步回调函数,来处理系统相关的事件。当你配置一个dispatch source时,你指定要监测的事件、dispatch queue、以及处理事件的代码(block或函数)。当事件发生时,dispatch source会提交你的block或函数到指定的queue去执行和手工提交到queue的任务不同,dispatch source为应用提供连续的事件源。除非你显式地取消,dispatch source会一直保留与dispatch queue的关联。只要相应的事件发生,就会提交关联的代码到dispatch queue去执行。
为了防止事件积压到dispatch queue,dispatch source实现了事件合并机制。如果新事件在上一个事件处理器出列并执行之前到达,dispatch source会将新旧事件的数据合并。根据事件类型的不同,合并操作可能会替换旧事件,或者更新旧事件的信息。
- 可以使用GCD的dispatch source功能来监视文件描述符、计时器、联结的用户事件以及其他类似的行为。由于dispatch source完全与dispatch queue相集成,所以可以使用任意的dispatch queue。可以将一个dispatch source的句柄在主线程中执行、在全局队列中并发执行、或者在用户队列中串行执行(执行时会将程序的其他模块的运算考虑在内)。
Dispatch Sources的具体实现
网友评论