串行队列上dispatch_async和dispatch_sync之间的区别?

JRG*_*per 120 multithreading grand-central-dispatch ios

我已经创建了一个这样的串行队列:

    dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);
Run Code Online (Sandbox Code Playgroud)

dispatch_async叫做这样的有什么区别

 dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_async(_serialQueue, ^{ /* TASK 2 */ });
Run Code Online (Sandbox Code Playgroud)

dispatch_sync像这样调用这个串行队列?

 dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });
Run Code Online (Sandbox Code Playgroud)

我的理解是,无论使用哪种调度方法,TASK 1都会在执行和完成之前TASK 2,对吗?

Bry*_*hen 402

是.使用串行队列可确保任务的串行执行.唯一的区别是dispatch_sync只有在块完成后才返回,而dispatch_async在将它添加到队列后返回并且可能没有完成.

这个代码

dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");
Run Code Online (Sandbox Code Playgroud)

它可以打印2413214312341总是前3

这个代码

dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");
Run Code Online (Sandbox Code Playgroud)

它总是打印 1234


注意:对于第一个代码,它不会打印1324.因为执行后被printf("3")调度.并且任务只能在调度执行. printf("2")


任务的执行时间不会改变任何事情.此代码始终打印12

dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); });
dispatch_async(_serialQueue, ^{ printf("2"); });
Run Code Online (Sandbox Code Playgroud)

可能发生的事情是

  • 线程1:dispatch_async一个耗时的任务(任务1)到串行队列
  • 线程2:开始执行任务1
  • 线程1:dispatch_async另一个任务(任务2)到串行队列
  • 线程2:任务1完成.开始执行任务2
  • 线程2:任务2完成.

而你总是看到 12

  • 它还可以打印2134和1243 (6认同)

Dav*_*ong 18

dispatch_sync和之间的区别dispatch_async很简单.

在两个示例中,TASK 1将始终执行,TASK 2因为它是在它之前调度的.

dispatch_sync但是,在示例中,在调度和执行TASK 2之后才会发送.这称为"阻塞".您的代码等待(或"阻止"),直到任务执行.TASK 1

在该dispatch_async示例中,您的代码不会等待执行完成.两个块都将分派(并入队)到队列中,其余代码将继续在该线程上执行.然后在将来的某个时刻(取决于已经分派给队列的其他内容),Task 1将执行然后Task 2执行.

  • 我认为你的订单错了.第一个例子是`async`,它是非阻塞版本 (2认同)

rd_*_*rd_ 6

这一切都与主队列有关。有4种排列。

i) 串行队列,异步调度:这里的任务将一个接一个地执行,但主线程(对 UI 的影响)不会等待返回

ii) 串行队列,调度同步:这里的任务会一个接一个执行,但主线程(对UI的影响)会出现滞后

iii) 并发队列,异步调度:这里的任务将并行执行,主线程(对 UI 的影响)不会等待返回并且会很流畅。

iv) 并发队列,调度同步:这里的任务将并行执行,但主线程(对 UI 的影响)会出现滞后

您选择并发队列还是串行队列取决于您是否需要为下一个任务提供前一个任务的输出。如果依赖上一个任务,则采用串行队列,否则采用并发队列。

最后,这是一种在我们完成业务后返回到主线程的方法:

DispatchQueue.main.async {
     // Do something here
}
Run Code Online (Sandbox Code Playgroud)