GCD
什么是GCD?
Grand Center Dispatch大中心调度
GCD是异步执行任务的技术之一。
一般,将应用程序中记述的线程管理用的代码在系统级中实现,开发者只需要定义想执行的任务并追加到适当的 Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。
现在一个物理的CPU芯片实际上有64个(64核)CPU,如果一个CPU核虚拟为两个CPU核工作,那么一台计算机上使用多个CPU核就是理所当然的事了。
1个CPU核一次能够执行的CPU命令始终为1。
由于使用多线程的程序可以在某个线程和其他线程之间反复多次进行上下文切换,因此看上去就好像1个CPU核能够并列地执行多个程序一样。而且在具有多个CPU核的情况下,就不是”看上去像“了,而是真的提供了多个CPU核并执行多个线程的技术。
这种利用了多线程编程的技术就被称为”多线程编程“。
但多线程也会造成一些潜在问题:
GCD的API
开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。
dispatch_async (queue, ^{
//想执行的任务
});
iOS和OS X的核心 – XUN内核决定应当使用的线程数,并只生成所需的线程执行处理。另外,当处理结束,应当执行的处理数减少时,XUN内核会结束不再需要的线程。
dispatch_after函数,并不是在指定时间后执行处理,而只是在指定时间追加处理到Dispatch Queue。
dispatch_async函数的"async"意味着”非同步“(asynchronous),就是将指定的Block”非同步“追加到指定的 Dispatch Queue中。dispatch_async函数不做任何等待。
dispatch_sync函数,它意味着”同步“(synchronous),也就是将指定的Block”同步“追加到指定的Dispatch Queue中。在追加Block结束之前,dispatch_sync函数会一直等待。
dispatch_suspend/dispatch_resume
当追加大量处理到 Dispatch Queue时,在追加处理的过程中,有时希望不执行已追加的处理。
dispatch_suspend 函数挂起指定的Dispatch Queue
dispatch_suspend(queue);
dispatch_resume 函数恢复指定的Dispatch Queue
dispatch_resume(queue);
异步大量的添加操作,会因为内存错误导致应用异常结束的概率很高。
因此,此处可以使用dispatch_semaphore_t。
dispatch_semaphore_t是持有计数的信号,该计数是多线程编程中的计数类型信号。
计数为0时等待,计数为1或大于1时,减去1而不等待。
GCD实现
- 用于管理追加的Block的C语言层实现的FIFO队列
- Atomic函数中实现的用于排他控制的轻量级信号
- 用于管理线程的C语言层实现的一些容器
通常,应用程序中编写的线程管理用的代码要在系统级实现
编程人员所使用GCD的API全部为包含在 libdispatch库中的C语言函数。Dispatch Queue通过结构体和链表,被实现为FIFO队列。FIFO队列管理是通过 dispatch_async等函数所追加的Block。
Block 并不是直接加入 FIFO 队列,而是先加入 Dispatch Continuation 这— dispatch_continuation_t类型结构体中,然后再加入 FIFO 队列。该 Dispatch Continuation 用于记忆 Block 所属的 Dispatch Group 和其他一些信息,相当于一般常说的执行上下文。
Dispatch Queue 可通过 dispatch_set_target_queue 函数设定,可以设定执行该 Dispatch Queue处理的 Dispatch Qucue 为目标。该目标可像串珠子一样,设定多个连接在一起的 Dispatch Queue。但是在连接串的最后必须设定为 Main Dispatch Queue, 或各种优先级的 Global Dispatch Queue,或是准备用于 Serial Dispatch Queue 的各种优先级的 Global Dispatch Queue。
Main Dispatch Queue 在 RunLoop 中执行 Block。