user3430104
user3430104

Reputation:

Grand Central Dispatch Nested Queues and Different Queue Priorities

I see a lot of use of GCD in the following format:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{         
     //do something it may take time here            
     dispatch_async(dispatch_get_main_queue(), ^
     {
          //UI updates on main
     });       
});       

It's understandable. But my imagination runs a little wild and I thought what would happen if someone did some like the following?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
    {
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
          {
              dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
              {                     
                  dispatch_async(dispatch_get_main_queue(), ^
                  {

                  });       
              });   
          });
    });
});

And even worse, what if they use a mixture of DISPATCH_QUEUE_PRIORITY_BACKGROUND, DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_HIGH in the above?

I am not saying the above is good, as I just want to learn to to read it and especially in general how do we read nested GCD queues (and the case when a mixture of QUEUE_PRIORITY is used)?

My understand is this (may sound funny):

Nested queues are like rooms within a house, no matter how many rooms within rooms I go into, I am still within the house. Other words, no matter how many nestings there are (like the above), I am still on the queue that is define on the outermost queue.

Hope my analogy is understandable. Hope someone can tell me how to read complicated nested queues / nested queues with different queue priorities. Thanks.

Upvotes: 2

Views: 701

Answers (2)

gnasher729
gnasher729

Reputation: 52632

I think you have the wrong mental image when you think of this as "nested queues". Your second example creates one relatively complex block A, and dispatches it to a queue. The queue contains a list of blocks that need executing, dispatching a block to the queue means adding that block at the end of that list. Nothing happens until that block starts executing.

When the block A starts executing, it creates another block B and appends it at the end of some queue, and then block A finishes. There may have been some other blocks dispatched in-between, but eventually block B arrives at the start of its queue and starts executing. It creates block C and adds it to the end of another queue, and so on. There is nothing nested going on.

Upvotes: 1

Greg Parker
Greg Parker

Reputation: 8012

Your analogy is reasonable for dispatch_sync() with serial queues. If you are running on one queue, and you dispatch_sync() to a second queue, then the code that runs will block anything else dispatched to those two queues until it completes. In that sense it is "running on" both queues.

The analogy does not work for dispatch_async(). If you are running on one queue, and dispatch_async() to a second queue, the code that runs has no association with the first queue. While that code runs, the first queue could run something else, or do nothing, or even be deleted. Only work items dispatched to the second queue are blocked until that code completes.

Be careful with dispatch priority. dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT) and dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW) return two completely different queues. It is not one global queue with multiple priorities; it is instead multiple global queues, one queue for each priority.

Upvotes: 2

Related Questions