If I have a dispatch_sync call followed by a second dispatch call in the dispatch_async block, does it matter if this second call is synchronous or asynchronous?

This code is suitable for a fairly standard situation where I have a data model, some of which potentially slow down data retrieval, and I want to update my view with data after the data lookup is complete.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
    dispatch_sync(queue, ^{
        //get a bunch of data
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
        [viewcontroller tellViewToReloadData];
    }
}

      

My question here is, does it matter if the second dispatch_sync was instead of dispatch_async?

This is my understanding of what is happening with the above code (I also use this as an opportunity to gauge my understanding of this general topic):

  • The outer dispatch_async returns immediately, and a block with two dispatch calls is placed on the parallel queue.

  • At some point, the outer asynchronous block will be executed on some random thread, after which the first dispatch_sync will be called and its block will be placed in a parallel queue.

  • At some point, the internal first sync block will perform all my data collection operations on some random thread, and only when they are all completed will the first dispatch_sync and the second dispatch_sync be returned.

  • The second call dispatch_sync is called, and the block with the code to update the view is placed on the main queue. At some point this block is executed and the view is updated and the second dispatch_sync is returned.

  • The outer block is now completing, so the parallel queue is free to push the task to the thread running the outer block.

Now I understand that if this second dispatch_sync was instead of calling dispatch_async, the only change is that the thread executing the outer block is busy for a slightly shorter amount of time because it doesn't need to wait for a block on the main queue to finish executing. It's right? By this reasoning, it seems slightly better if the second dispatch_sync is dispatch_async just because some thread will be busy for a (possibly trivially) shorter time, but it doesn't really matter much.

+3


source to share


1 answer


  • The first sync is pointless - you're already there queue

    .

    dispatch_async(queue, ^{
        //get a bunch of data
        dispatch_sync(dispatch_get_main_queue(), ^{
            [viewcontroller tellViewToReloadData];
        });
    });
    
          

  • sync

    is simply async

    with a pending primitive, as if it were:

    dispatch_semaphore_t s = dispatch_semaphore_create(0);
    
    dispatch_async(queue, ^{
        [viewcontroller tellViewToReloadData];
        dispatch_semaphore_signal(s);
    });
    
    dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);
    
          

Now I understand that if this second dispatch_sync was instead of calling dispatch_async, the only change is that the thread executing the outer block is busy for a slightly shorter amount of time because it doesn't need to wait for a block on the main queue to finish executing. Is it correct?

Yes.



For these reasons, it seems that the second dispatch_sync for dispatch_sync is slightly better because some thread will be busy for a (possibly trivially) shorter time, but it doesn't really matter much.

This can be useful in situations where many threads get stuck waiting for the main thread to complete the load under load. The system would then have to spawn more pthreads in order to continue to perform other concurrent tasks efficiently and close the excessive threads afterwards. Can't say if this applies, but obviously there is no need to wait if you don't want the results.

+2


source







All Articles