我已经创建了一个这样的串行队列:
dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
dispatch_async
之间的区别是什么?
dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
并且 dispatch_sync
在这个串行队列上调用了这个?
dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
我的理解是,无论使用哪种调度方法, TASK 1
都将在 TASK 2
之前执行并完成,对吗?
3 回答
是 . 使用串行队列可确保任务的串行执行 . 唯一的区别是
dispatch_sync
仅在块完成后返回,而dispatch_async
在添加到队列后返回并且可能未完成 .这个代码
它可能会在
3
之前打印2413
或2143
或1234
但1
这个代码
它总是打印
1234
注意:对于第一个代码,它不会打印
1324
. 因为printf("3")
在printf("2")
执行后被调度 . 并且任务只能在调度后执行 .任务的执行时间不会改变任何事情 . 此代码始终打印
12
可能发生的事情是
线程1:dispatch_async一个耗时的任务(任务1)到串行队列
线程2:开始执行任务1
线程1:dispatch_async另一个任务(任务2)到串行队列
线程2:任务1完成 . 开始执行任务2
线程2:任务2完成 .
你总是看到
12
dispatch_sync
和dispatch_async
之间的区别很简单 .在两个示例中,
TASK 1
将始终在TASK 2
之前执行,因为它在它之前被调度 .但是,在
dispatch_sync
示例中,在分派并执行TASK 1
之后,才会调度TASK 2
. 这叫做"blocking" . 您的代码等待(或"blocks"),直到任务执行 .在
dispatch_async
示例中,您的代码不会等待执行完成 . 两个块都将分派(并入队)到队列中,其余代码将继续在该线程上执行 . 然后在将来的某个时刻,(取决于已经分派给队列的其他内容),Task 1
将执行,然后Task 2
将执行 .它都与主队列有关 . 有4种排列 .
i)串行队列,调度异步:这里任务将一个接一个地执行,但主线程(对UI的影响)不会等待返回
ii)串行队列,调度同步:这里任务将一个接一个地执行,但主线程(对UI的影响)将显示滞后
iii)并发队列,调度异步:这里任务将并行执行,主线程(对UI的影响)不会等待返回并且将是平滑的 .
iv)并发队列,调度同步:这里任务将并行执行,但主线程(对UI的影响)将显示滞后
您选择的并发或串行队列取决于您是否需要上一个任务的输出以用于下一个任务 . 如果依赖于上一个任务,则采用串行队列,否则采用并发队列 .
最后,当我们完成业务时,这是一种渗透回主线程的方式: