Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dispatch_async vs. dispatch_sync using Serial Queues in Grand Central Dispatch

Tags:

OK, I love Grand Central Dispatch and after using it with relative success but this is something I don't fully understand.

Suppose I have created my own serial queue using

dispatch_queue_t myQueue;
myQueue = dispatch_queue_create("myQueue", NULL);

After that I do this:

dispatch_async(myQueue, ^{
  [self doStuff1];
});

// and a few lines later...

dispatch_sync(myQueue, ^{
  [self doStuff2];
});

The first dispatch is async. So, it will be done concurrently, right? How can that be if myQueue is serial? How can a serial queue do things in parallel or, if you will, out of order?

thanks

like image 269
Duck Avatar asked Feb 17 '11 07:02

Duck


People also ask

Which of the following queues are used in Grand Central Dispatch?

Understanding Queues As mentioned before, GCD operates on dispatch queues through a class aptly named DispatchQueue . You submit units of work to this queue, and GCD executes them in a FIFO order (first in, first out), guaranteeing that the first task submitted is the first one started.

What is difference between serial and concurrent queue?

Since its concurrent queue, tasks may not finish in the order they are added to queue. But with synchronous operation it does although they may be processed by different threads. So, it behaves as this is the serial queue. Remember using GCD you are only adding task to the Queue and performing task from that queue.

Is global queue serial or concurrent?

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue.

Are dispatch queues thread safe?

Yes, the dispatch queue objects, themselves, are thread-safe (i.e. you can safely dispatch to a queue from whatever thread you want), but that doesn't mean that your own code is necessarily thread-safe.


3 Answers

dispatch_async() means that the block is enqueued and dispatch_async()returns to enqueueing another task/block (possibly) prior to the block being executed.

With dispatch_sync(), the block is enqueued and the function will not continue enqueueing another task/block until the block is executed.

The blocks are still executed serially. You could execute 100 dispatch_async() calls, each with a block that sleeps for 100 seconds, and it'd be really fast. Follow that with a call to dispatch_sync() on the same serial queue and dispatch_sync() will return ~10,000 seconds later.


To put it more simply:

dispatch_async(serialQ, block1);
dispatch_async(serialQ, block2);
dispatch_sync(serialQ, block3);

block1 will be executed before block2 which will be executed before block3. That is the order guaranteed by the serial queue.

However, the calls to dispatch_async() may return before any of the blocks start executing. The dispatch_sync() will not return before all three blocks are executed!

like image 170
bbum Avatar answered Oct 20 '22 11:10

bbum


Neither dispatch_async or dispatch_sync change the way the block gets queued. If the queue is serial, the blocks will execute in a serial manner, if the queue is concurrent, in a concurrent manner.

The important difference between the two is that dispatch_sync queues the block and waits on the current execution thread until that block is executed and dispatch_async just queues the block and continues the execution of the subsequent instructions.

like image 32
Rad'Val Avatar answered Oct 20 '22 10:10

Rad'Val


Serial Queue can only run a single task at a time,irrespective of sync or async. Serial queues are allocated only one thread. This will be easier to understand using the below example -

Suppose there are 2 Queues A and B running tasks T1 and T2 respectively and T1 is being executed asynchronously. If control passes from A to B and B runs T2 synchronously then till the time the T2(block of code in the dispatch_sync block) completes execution T1 will be blocked. When T2 completes then T1 will resume it's execution.

like image 30
Gaurav_Sharma08 Avatar answered Oct 20 '22 10:10

Gaurav_Sharma08