Grand Central Dispatch(GCD)是异步执行任务的技术之一。一般将应用程序中记述的线程管理用的代码在系统级中实现。开发者只需要定义想执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务。由于线程管理是作为系统的一部分来实现的,因此可统一管理,也可执行任务,这样就比以前的线程更有效率。
Dispatch Queue
官方的说明是:开发者要做的只是定义想执行的任务并所加到适当的Dispatch Queue中。
dispatch_async(queue, ^{
/*
* 要执行的任务
*/
});
该源代码使用Block语法定义了想执行的任务,通过dispatch_async函数“追加”赋值在变量queue的“Dispatch Queue”中。这样就可使指定的Block在另一线程中执行。
“Dispatch Queue”是什么呢?如其名称所示,是执行处理的等待队列。我们通过dispatch_async等API函数,在Block语法中定义想执行的任务并将其追加到Dispatch Queue中。
在执行处理任务时,存在两个Dispatch Queue,一种是等待现在执行中处理的Serial Dispath Queue;另一种是不等待现在执行中处理的Concurrent Dispatch Queue。
例:
dispatch_async(queue, block0);
dispatch_async(queue, block1);
dispatch_async(queue, block2);
dispatch_async(queue, block3);
dispatch_async(queue, block4);
dispatch_async(queue, block5);
dispatch_async(queue, block6);
dispatch_async(queue, block7);
当变量queue为Serial Dispatch Queue时,因为要等待现在执行中的处理结束,所以首先执行block0。block0执行结束后,接着执行block1,block1结束后再开始执行block2,如此重复,直到block7执行结束。同时执行的处理数只能有1个。即执行该源代码后,一定按照以下顺序进行处理:
block0
block1
block2
block3
block4
block5
block6
block7
当变量queue为Concureent Dispatch Queue时,因为不用等待现在执行中的处理结束,所以首先执行block0,不管理block0是否执行结束,都直接开始执行后面的block1,也不管block1的执行是否结束,开始执行后面的block2,如此重复。
这样虽然不用等待处理结束,可以并行执行多个处理,但并行执行的处理数量取决于当前系统的状态。即iOS和OS X基于Dispatch Queue中的处理数、CPU核数以及CPU负荷等当前系统的状态来决定Concurrent Dispath Queue中并行执行的处理数。所谓“并行执行”,就是使用多个线程同时执行多个处理。
即 Dispatch Queue使用一个线程
Concurrent Dispatch Queue使用多个线程。
iOS和OS X的核心——XNU内核决定应当使用的线程数,并只生成所需的线程执行处理。另外,当处理结束,应当执行的处理数减少时,XNU内核会结束不再需要的线程。XNU内核仅使用Concurrent Dispath Queue便可完美地管理并行执行多个处理的线程。
例如,前面的源代码如下表如所:在多个线程中执行Block。
线程0 | 线程1 | 线程2 | 线程3 |
block0 | block1 | block2 | block3 |
block4 | block6 | block5 | |
block7 | | | |
假设准备4个Concurrent Dispatch Queue用线程。首先block0在线程0中开始执行,接着block1在线程1中、block2在线程2中、block3在线程3中开始执行。线程0中block0执行结束后开始执行block4,由于线程1的block1的执行没有结束,因此线程2中的block2执行线束后开始执行block5,这样循环往复。
像这样在Concurrent Dispatch Queue中执行处理时,执行顺序会根据处理内容和系统状态发生改变。它不同于执行顺序固定的Serial Dispatch Queue。在不能改变执行的处理顺序或不想并行执行多个处理时使用Serial Dispatch Queue。
虽然知道了有Serial Dispatch Queue和Concurrent Dispatch Queue这两种,但如何才能得到这些Dispatch Queue呢?方法有两种: