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

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

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之前执行并完成,对吗?

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

为此代码

 dispatch_async(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_async(_serialQueue, ^{ printf("3"); }); printf("4"); 

它可以打印241321431234但总是在3之前

为此代码

 dispatch_sync(_serialQueue, ^{ printf("1"); }); printf("2"); dispatch_sync(_serialQueue, ^{ printf("3"); }); printf("4"); 

它总是打印1234


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


任务的执行时间不会改变任何东西。 这个代码总是打印12

 dispatch_async(_serialQueue, ^{ sleep(1000);printf("1"); }); dispatch_async(_serialQueue, ^{ printf("2"); }); 

可能发生的事情是

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

你总是看到12

dispatch_syncdispatch_async之间的区别很简单。

在你的两个例子中, TASK 1总是在TASK 2之前执行,因为它在它之前被调度。

然而,在dispatch_sync示例中,直到TASK 1被分派并执行之后,您才会调度TASK 2 。 这被称为“阻塞” 。 您的代码将等待(或“阻止”),直到执行任务。

dispatch_async示例中,您的代码不会等待执行完成。 两个块都将调度(并入队)到队列中,其余的代码将继续在该线程上执行。 然后在将来的某个时刻,(取决于还有什么被派往你的队列), Task 1将被执行,然后Task 2将被执行。