Ios – Difference between dispatch_async and dispatch_sync on serial queue

grand-central-dispatchiosmultithreading

I've created a serial queue like this:

    dispatch_queue_t _serialQueue = dispatch_queue_create("com.example.name", DISPATCH_QUEUE_SERIAL);

What's the difference between dispatch_async called like this

 dispatch_async(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_async(_serialQueue, ^{ /* TASK 2 */ });

And dispatch_sync called like this on this serial queue?

 dispatch_sync(_serialQueue, ^{ /* TASK 1 */ });
 dispatch_sync(_serialQueue, ^{ /* TASK 2 */ });

My understanding is that, regardless of which dispatch method is used, TASK 1 will be executed and completed before TASK 2, correct?

Best Answer

Yes. Using serial queue ensure the serial execution of tasks. The only difference is that dispatch_sync only return after the block is finished whereas dispatch_async return after it is added to the queue and may not finished.

for this code

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

It may print 2413 or 2143 or 1234 but 1 always before 3

for this code

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

it always print 1234


Note: For first code, it won't print 1324. Because printf("3") is dispatched after printf("2") is executed. And a task can only be executed after it is dispatched.


The execution time of the tasks doesn't change anything. This code always print 12

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

What may happened is

  • Thread 1: dispatch_async a time consuming task (task 1) to serial queue
  • Thread 2: start executing task 1
  • Thread 1: dispatch_async another task (task 2) to serial queue
  • Thread 2: task 1 finished. start executing task 2
  • Thread 2: task 2 finished.

and you always see 12