Difference between dispatch_async and dispatch_sync on serial queue?
The difference between dispatch_sync
and dispatch_async
is simple.
In both of your examples, TASK 1
will always execute before TASK 2
because it was dispatched before it.
In the dispatch_sync
example, however, you won't dispatch TASK 2
until after TASK 1
has been dispatched and executed. This is called "blocking". Your code waits (or "blocks") until the task executes.
In the dispatch_async
example, your code will not wait for execution to complete. Both blocks will dispatch (and be enqueued) to the queue and the rest of your code will continue executing on that thread. Then at some point in the future, (depending on what else has been dispatched to your queue), Task 1
will execute and then Task 2
will execute.
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