一、什么是GCD?
Grand Central Dispatch 是异步执行任务的技术之一。
使用了简洁的方法,实现了极为复杂的多线程编程
。
GCD 的常用API
1、 认识队列
1)串行队列和并发队列
串行队列
:FIFO,后面一个等上一个任务完,只可用于一个线程。
并发队列
:可以随意取,不按照顺序, 可以用于多线程
dispatch_queue_t dispatch_queue_create(const char *_Nullable DISPATCH_UNSAFE_INDEXABLE label,
dispatch_queue_attr_t _Nullable attr);
// label: 是队列标识
// attr : 设置生成队列的属性,是串行还是并发
2)Main Dispatch Queue(主队列)/ Global Dispatch Queue(全局队列)
主队列
: 主线程队列,将用户界面等一些必须在主线程执行的处理追加到主队列中。
全局队列
: 所有应用程序都能够使用的并发队列,可以设置等级,高->低【4级】。
0x01: void dispatch_set_target_queue(dispatch_object_t object,dispatch_queue_t _Nullable queue)
1)不管是串行队列还是并行对垒,都使用了与全局队列相同的优先级,这个方法变更了队列执行的优先级。
参数一: 指定要变更优先级的队列
参数二: 指定要使用的优先级的队列,也就是让第一个参数和第二个参数的优先级一样。
2)扩展使用:对队列进行设置优先级阶层。通过设置队列的依赖关系而实现的执行阶层 —— 可以防止并行执行。
如果多个串行队列中用该函数指定目标位某个串行队列,那么原本应并行执行的多个串行队列,在目标这些串行队列只能同时执行一个处理。
0x02: void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
并不是在指定时间后执行处理,而是在执行时间追加处理到Dispatch Queue 中。
常使用场景: 就是我们想在3秒之后再主线程中执行某个任务。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// do code
});
0x03: dispatch_group_t
多个处理结束之后,再处理的事情。 常常使用的场景就是多个网络请求之后,再重新组装数据。
0x04:dispatch_barrier_async
执行栅栏, 主要是为了分割执行代码块。
常常使用的场景:访问数据库或者文件,使用串行队列,可以避免数据竞争的问题。 因为写入数据确实不可与其他的写入处理以及包含读取处理的其他某些处理并行执行。但是如果是读取处理只是与读取处理并行执行,那么多个并行执行就不会发生问题。
为了搞笑的访问,读取处理追加到并发队列中,写入处理在任一个读取没有执行的状态下,追加到串行队列中即可
0x05:dispatch_sync
同步处理, 用于同步队列执行任务
0x06: dispatch_async
异步处理,用于异步执行队列任务。
0x07:dispatch_apply
按指定的次数将指定的block追加到指定的Dispatch Queue中,并等待全部处理执行结束。
是和dispatch_sync和dispatch group 有关联的API。
0x08: dispatch_suspend/dispatch_resume
希望不执行已追加到queue中的处理。 具有暂停/恢复 执行的作用。
0x09: dispatch semaphore
GCD 中实现的信号量,用来控制线程同步的问题。
0x10: dispatch_once
保证在应用程序中只执行一次指定处理的API。
常用于创建一个单例。
Dispatch I/O 提高文件的读取速度
已经常想的是:在读取大文件时候,如果将文件分成合适的大小并使用Global Dispach Queue并列读取的话,应该会比一般的读取速度快不少。
现今的输入/输出硬件已经可以做到一次使用多个线程更快的并列读取了。 就是dispatch I/O
GCD 是如何实现的?
Disaptch Queue
Dispatch Source
本文由mdnice多平台发布