工作中用到了一点儿线程同步异步的知识,作点儿笔记,以备查阅。
模拟一个情景。我要从服务器下载4张图片,之后将四张图片拼接成一张,显而易见,图片这种耗时操作我们肯定要在子线程去完成该任务,由于图片的大小可能还不一样,我们分别开4个异步的任务去分别下载4张图片,但是问题来了,我拼接4张图片的时候必这四张图片必须全部都下载完成了才能进行,面对这样的场景,我来给大家介绍两个可以实现上述逻辑的方法,使用dispatch_barrier_async或dispatch_group_async
看一段代码
打印结果
线程的调度时间是不能控制的。
dispatch_barrier_async
相关的打印信息
dispatch_barrier的含义是:一个并发队列中创建一个同步点。并发队列中遇到一个barrier, 他会延迟执行barrier的block,等待所有在barrier之前提交的blocks执行结束。 这时,barrier block自己开始执行.后面的 队列继续正常的执行操作。
只是使用一个串行队列时,只要将想执行的处理全部追加到该串行队列中并在最后追加结束处理即可,但是在使用并发队列时,可能会同时使用多个Dispatch Queue时,源代码就会变得很复杂
dispatch_group_async
相关的打印信息
同样的上面的任务执行完毕后会调用dispatch_group_notify这个函数,按照这个思路我们依然实现上面图片的下载和拼接操作.
最后关于dispatch_barrier_sync和dispatch_barrier_async,同步和异步问题。
dispatch_barrier_sync同步
结果
栅栏函数确实分割了任务,但是dispatch_barrier_sync的顺序的确是有序的(同步函数)
dispatch_barrier_async异步
结果
栅栏函数确实分割了任务,但是dispatch_barrier_async的顺序的确是无序的(异步函数)
区别:官方文档
dispatch_barrier_sync: Submits a barrier block object for execution and waits until that block completes.(提交一个栅栏函数在执行中,它会等待栅栏函数执行完)
dispatch_barrier_async: Submits a barrier block for asynchronous execution and returns immediately.(提交一个栅栏函数在异步执行中,它会立马返回)
作者理解:dispatch_barrier_sync 需要等待栅栏执行完才会执行栅栏后面的任务,而dispatch_barrier_async 无需等待栅栏执行完,会继续往下走(保留在队列里)
原因:在同步栅栏时栅栏函数在主线程中执行,而异步栅栏中开辟了子线程栅栏函数在子线程中执行
Note:
The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_sync function.
官方大意是:使用栅栏函数时.使用自定义队列才有意义,如果用的是串行队列或者系统提供的全局并发队列,这个栅栏函数的作用等同于一个同步函数的作用。
网友评论