资源预览内容
第1页 / 共12页
第2页 / 共12页
第3页 / 共12页
第4页 / 共12页
第5页 / 共12页
第6页 / 共12页
第7页 / 共12页
第8页 / 共12页
第9页 / 共12页
第10页 / 共12页
亲,该文档总共12页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
文档供参考,可复制、编制,期待您的好评与关注! 并发编程之GCD在并发编程之Operation Queue中讲了Cocoa并发编程中的Operation Queue,了解了Operation Queue是一个面向对象的并发编程接口,它支持并发数,线程优先级,任务优先级,任务依赖关系等多种配置,可以方便满足各种复杂的多任务处理场景。本篇将接着讲另一种并发编程机制 GCD(Grand Central Dispatch)。iOS4.0中首度引入GCD,GCD是管理任务执行的一项技术,它使得我们对多任务处理变得更加方便和有效。它支持同步或异步任务处理,串行或并行的处理队列(Dispath Queue),非系统调用的信号量机制,定时任务处理,进程、文件或网络的监听任务等。这个庞大的任务处理技术大大减少了线程的管理工作,使基于任务的开发变得更加高效。Dispatch QueueDispatch Queue是一个任务执行队列,可以让你异步或同步地执行多个Block或函数。Dispatch Queue是FIFO的,即先入队的任务总会先执行。目前有三种类型的Dispath Queue:1.串行队列(Serial dispatch queue)2.并发队列(Concurrent dispatch queue)3.主队列(Main dispatch queue)串行队列串行队列一次只能处理一个任务,可以由用户调用dispatch_queue_create创建:1. dispatch_queue_tqueue;2. queue=dispatch_queue_create(com.example.MyQueue,NULL);dispatch_queue_create第一个参数是串行队列标识,一般用反转域名的格式表示以防冲突;第二个参数是queue的类型,设为NULL时默认是DISPATCH_QUEUE_SERIAL,将创建串行队列,在必要情况下,你可以将其设置为DISPATCH_QUEUE_CONCURRENT来创建自定义并行队列。并行队列并行队列可以同时处理多个任务,在不得以的情况下可以用dispatch_queue_create创建,但一般我们都要用系统预定义的并行队列,即全局队列(Global Concurrent Dispatch Queues)。目前系统预定义了四个不同运行优先级的全局队列,我们可以通过dispatch_get_global_queue来获取它们。1. dispatch_queue_taQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);dispatch_get_global_queue第一个参数是队列的优先级,分别对应四个全局队列:DISPATCH_QUEUE_PRIORITY_HIGHDISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_BACKGROUNDdispatch_get_global_queue中第二个参数目前系统保留,请设置为0即可。主队列主队列是一个特殊的队列,它是系统预定义的运行在主线程的一个Dispatch Queue。可以通过dispatch_get_main_queue来获取唯一的主队列。主队列一般运行一些需要与主线程同步的一些短时任务。1. dispatch_queue_tmainQueue=dispatch_get_main_queue();获取当前队列你可以通过dispatch_get_current_queue获取运行时的队列:1. dispatch_queue_tcurrentQueue=dispatch_get_current_queue();如果在队列执行任务中调用,返回执行此任务的队列;如果在主线程中调用,将返回主队列;如果在一般线程(非主线程线程非队列执行任务)中调用,返回DISPATCH_QUEUE_PRIORITY_DEFAULT全局队列。在队列中运行任务你可以随时向一个队列中添加一个新任务,只需要调用一下dispatch_async即可:1. dispatch_async(aQueue,2. /Dosomework;3. );dispatch_async中的任务是异步执行的,就是说dispatch_async添加任务到执行队列后会立刻返回,而不会等待任务执行完成。然而,必要的话,你也可以调用dispatch_sync来同步的执行一个任务:1. dispatch_sync(aQueue,2. /Dosomework;3. );dispatch_sync会阻塞当前线程直到提交的任务完全执行完毕。Dispatch Queue的内存管理除了系统预定义的Dispatch Queue,我们自定义的Dispatch Queue需要手动的管理它的内存。dispatch_retain和dispatch_release这两个函数可以控制Dispatch Queue的引用计数(同时可以控制后面会讲到的Dispatch Group和Dispatch Source的引用计数)。当Dispatch Queue引用计数变为0后,就会调用finalizer,finalizer是Dispatch Queue销毁前调用的函数,用来清理Dispatch Queue的相关资源。可以用dispatch_set_finalizer_f函数来设置Dispatch Queue的finalizer,这个函数同时可以设置Dispatch Group和Dispatch Source的销毁函数(后面会讲到)。1. voiddispatch_set_finalizer_f(dispatch_object_tobject,dispatch_function_tfinalizer);Dispatch Queue的上下文环境数据我们可以为每个Dispatch Queue设置一个自定义的上下文环境数据,调用dispatch_set_context来实现。同时我们也可以用dispatch_get_context获取这个上下文环境数据,这个函数同时可以设置Dispatch Group和Dispatch Source的上下文环境数据(后面会讲到)。1. voiddispatch_set_context(dispatch_object_tobject,void*context);2. void*dispatch_get_context(dispatch_object_tobject);注意Dispatch Queue并不保证这个context不会释放,不会对它进行内存管理控制。我们需要自行管理context的内存分配和释放。一般我们非配内存设置context后,可以在finalizer里释放context占有的内存。并行执行循环在编程过程中,我们经常会用到for循环,而且for循环要做很多相关的任务。比如:1. for(i=0;icount;i+)2. /doalotofworkhere.3. doSomething(i);4. 如果for循环中处理的任务是可并发的,显然放到一个线程中处理是很慢的,GCD提供两个函数dispatch_apply和dispatch_apply_f,dispatch_apply是用于Block的,而dispatch_apply_f可以用于c函数,它们可以替代可并发的for循环,来并行的运行而提高执行效率。1. dispatch_queue_tqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);2. dispatch_apply(count,queue,(size_ti)3. /doalotofworkhere.4. doSomething(i);5. );Dispatch Group有时候我们进行下一步操作,而这个操作需要等待几个任务处理完毕后才能继续,这时我们就需要用的Dispatch Group(类似thread join)。我们可以把若干个任务放到一个Dispatch Group中:1. dispatch_queue_tqueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);2. dispatch_group_tgroup=dispatch_group_create();3. dispatch_group_async(group,queue,4. /Someasynchronouswork5. );dispatch_group_async跟dispatch_async一样,会把任务放到queue中执行,不过它比dispatch_async多做了一步操作就是把这个任务和group相关联。把一些任务放到Dispatch Group后,我们就可以调用dispatch_group_wait来等待这些任务完成。若任务已经全部完成或为空,则直接返回,否则等待所有任务完成后返回。注意:返回后group会清空。1. dispatch_group_wait(group,DISPATCH_TIME_FOREVER);2. /Dosomeworkafter.3. dispatch_release(group);Dispatch信号量很多程序设计都设计到信号量,生产者-消费者模型在多线程编程中会频繁的使用。GCD提供了自己的一套信号量机制。1. dispatch_semaphore_tsema=dispatch_semaphore_create(RESOURCE_SIZE);2. dispatch_semaphore_wait(sema,DISPATCH_TIME_FOREVER);3. /dosomeworkhere.4. dispatch_semaphore_signal(sema);dispatch_semaphore_wait用来获取信号量,若信号量为0,则等待直到信号量大于0。在处理任务结束后,应释放相关资源并调用dispatch_semaphore_signal使信号量增加1个。Dispatch SourceDispatch Source是GCD中监听一些系统事件的有个Dispatch对象,它包括定时器、文件监听、进程监听、Mach port监听等类型。可以通过dispatch_source_create创建一个Dispatch Source:1. dispatch_source_tdispatch_source_create(2. dispatch_source_type_ttype,3. uintptr_thandle,4. unsignedlongmask,5. dispatch_queue_tqueue);这里可以指定Dispatch
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号