index仅此而已的专栏

dispatch队列的生成可以有这几种方式:

1. dispatch_queue_tqueue =dispatch_queue_create("com.dispatch.serial",DISPATCH_QUEUE_SERIAL);//生成一个串行队列,队列中的block按照先进先出(FIFO)的顺序去执行,实际上为单线程执行。第一个参数是队列的名称,在调试程序时会非常有用,所有尽量不要重名了。

2. dispatch_queue_tqueue =dispatch_queue_create("com.dispatch.concurrent",DISPATCH_QUEUE_CONCURRENT);//生成一个并发执行队列,block被分发到多个线程去执行

3.dispatch_queue_tqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//获得程序进程缺省产生的并发队列,可设定优先级来选择高、中、低三个优先级队列。由于是系统默认生成的,所以无法调用dispatch_resume()和dispatch_suspend()来控制执行继续或中断。需要注意的是,三个队列不代表三个线程,可能会有更多的线程。并发队列可以根据实际情况来自动产生合理的线程数,也可理解为dispatch队列实现了一个线程池的管理,对于程序逻辑是透明的。

官网文档解释说共有三个并发队列,但实际还有一个更低优先级的队列,设置优先级为DISPATCH_QUEUE_PRIORITY_BACKGROUND。Xcode调试时可以观察到正在使用的各个dispatch队列。

4.dispatch_queue_tqueue =dispatch_get_main_queue();//获得主线程的dispatch队列,实际是一个串行队列。同样无法控制主线程dispatch队列的执行继续或中断。

并发与并行理解:

并发和并行通常被一起提到,所以值得花些时间解释它们之间的区别。

并发代码的不同部分可以“同步”执行。然而,该怎样发生或是否发生都取决于系统。多核设备通过并行来同时执行多个线程;然而,为了使单核设备也能实现这一点,它们必须先运行一个线程,执行一个上下文切换(Context Switch),然后运行另一个线程或进程。这通常发生地足够快以致给我们并发执行地错觉,如下图所示:

虽然你可以编写代码在 GCD 下并发执行,但 GCD 会决定有多少并行的需求。并行要求并发,但并发并不能保证并行。

dispatch队列还实现其它一些常用函数,包括:

voiddispatch_apply(size_titerations,dispatch_queue_tqueue,void(^block)(size_t));//重复执行block,需要注意的是这个方法是同步返回,也就是说等到所有block执行完毕才返回,如需异步返回则嵌套在dispatch_async中来使用。多个block的运行是否并发或串行执行也依赖queue的是否并发或串行。

voiddispatch_barrier_async(dispatch_queue_tqueue,dispatch_block_tblock);//这个函数可以设置同步执行的block,它会等到在它加入队列之前的block执行完毕后,才开始执行。在它之后加入队列的block,则等到这个block执行完毕后才开始执行。

voiddispatch_barrier_sync(dispatch_queue_tqueue,dispatch_block_tblock);//同上,除了它是同步返回函数

void dispatch_after(dispatch_time_twhen,dispatch_queue_tqueue,dispatch_block_tblock);//延迟执行block

最后再来看看dispatch队列的一个很有特色的函数:

voiddispatch_set_target_queue(dispatch_object_tobject,dispatch_queue_tqueue);

它会把需要执行的任务对象指定到不同的队列中去处理,这个任务对象可以是dispatch队列,,也可以是dispatch源(以后博文会介绍)。而且这个过程可以是动态的,可以实现队列的动态调度管理等等。比如说有两个队列dispatchA和dispatchB,这时把dispatchA指派到dispatchB:

dispatch_set_target_queue(dispatchA, dispatchB);

那么dispatchA上还未运行的block会在dispatchB上运行。这时如果暂停dispatchA运行:

dispatch_suspend(dispatchA);

则只会暂停dispatchA上原来的block的执行,dispatchB的block则不受影响。而如果暂停dispatchB的运行,则会暂停dispatchA的运行。

这里只简单举个例子,说明dispatch队列运行的灵活性,在实际应用中你会逐步发掘出它的潜力。

dispatch队列不支持cancel(取消),没有实现dispatch_cancel()函数,不像NSOperationQueue,不得不说这是个小小的缺憾。

我不但的回首,伫足,然后时光扔下我轰轰烈烈的向前奔去。

index仅此而已的专栏

相关文章:

你感兴趣的文章:

标签云: