GCD理解
-
- GCD
-
- Dispatch Queue
GCD
Dispatch Queue
执行处理的等待队列。应用程序编程人员通过dispatch_async函数等API,在Block语法中记述想执行的处理并将其追加到Dispatch Queue中,Dispatch Queue按照追加的顺序(先进先出FIFO)执行处理。
串行队列(Serial Dispatch Queue)
因为要等待现在执行中的处理结束,所以首先执行blk0,blk0执行结束后,接着执行blk1,blk1结束后再开始执行blk2,如此重复。同时执行的处理数只能有1个。
只在为了避免多线程编程问题之一——多个线程更新相同资源导致数据竞争时使用Serial Dispatch Queue
Serial Dispatch Queue的生成个数应当仅限所必需的数量,例如更新数据库时一个表生成一个Serial Dispatch Queue,更新文件时一个文件或是可以分割的1个文件块生成1个Serial Dispatch Queue。绝不能激动之下大量生成Serial Dispatch Queue
并发队列(Concurrent Dispatch Queue)
因为不用等待现在执行中的处理结束,所以首先执行blk0,不管blk0的执行是否结束,都开始执行后面的blk1,不管blk1的执行是否结束,都开始执行后面的blk2,如此重复循环
这样虽然不用等待处理结束,可以并行执行多个处理,但并行执行的处理数量取决于当前系统的状态。即iOS和OS X基于Dispatch Queue中的处理数,CPU核数以及CPU负荷等当前系统的状态来决定并发队列中并行执行的处理数
iOS和OS X的核心——XNU内核决定应当使用的线程数,并只生成所需的线程执行处理。另外,当处理结束,应当执行的处理数减少时,XNU内核会结束不再需要的线程。
假设准备4个Concurrent Dispatch Queue用线程,首先blk0再线程0中开始执行,接着blk1在线程1中、blk2在线程2中、blk3在线程3中开始执行。线程0中blk0执行结束后开始执行blk4,由于线程1中blk1的执行没有结束,因此线程2中blk2执行结束后开始执行blk5,就这样循环往复
dispatch_queue_create
dispatch_queue_create可生成Dispatch Queue,虽然Serial Dispatch Queue和Concurrent Dispatch Queue受到系统资源的限制,但用dispatch_queue_create函数可生成任意多个Dispatch Queue
当生成多个Serial Dispatch Queue时,各个Serial Dispatch Queue将并行执行。虽然在1个Serial Dispatch Queue中同时只能执行一个追加处理,但如果将处理分别追加到4个Serial Dispatch Queue中,各个Serial Dispatch Queue执行1个,即为同时执行4个处理。
对于Concurrent Dispatch Queue来说,不管生成多少,由于XNU内核只使用有效管理的线程,因此不会发生Serial Dispatch Queue的那些问题
在iOS6.0以下通过dispatch_queue_create生成的Dispatch Queue在使用结束后通过dispatch_release函数释放,iOS6.0以及以上ARC会自动管理
系统提供的Dispatch Queue
Main Dispatch Queue是在主线程执行的Dispatch Queue,因为主线程只有一个,所以Main Dispatch Queue自然就是Serial Dispatch Queue,追加到Main Dispatch Queue的处理在主线程的RunLoop中执行。
Global Dispatch Queue有四个执行优先级,4个全局队列,分别是高优先级(High Priority)、默认优先级(Default Priority)、低优先级(Low Priority)和后台优先级(Background Priority)。通过XNU内核管理的用于Global Dispatch Queue的线程,将各自使用的Global Dispatch Queue的执行优先级作为线程的执行优先级使用。
为创建的Dispatch Queue创建优先级
自己创建的Dispatch Queue优先级都使用与默认优先级Global Dispatch Queue相同执行优先级的线程。而变更自己创建的Dispatch Queue执行优先级要使用dispatch_set_target_queue函数
dispatch_queue_t mySerialDispatchQueue = dispatch_queue