Search code examples
iosobjective-cconcurrencygrand-central-dispatchdispatch-async

How does a serial dispatch queue guarantee resource protection?


//my_serial_queue is a serial_dispatch_queue

dispatch_async(my_serial_queue, ^{

    //access a shared resource such as a bank account balance
    [self changeBankAccountBalance];

});

If I submit 100 tasks that each access and mutate a bank account balance, I understand that a serial queue will execute each task sequentially, but do these tasks finish sequentially as well when using dispatch_async?

What if task #23 that I submit asynchronously to the serial queue takes a really long time to finish? Would task #24 start only when task #23 is done, or would task #24 begin before task #23 is done? If so, couldn't task #24 have the wrong bank account balance when it starts its job, thereby screwing up data integrity?

Thanks!!


Solution

  • man dispatch_queue_create says: “All memory writes performed by a block dispatched to a serial queue are guaranteed to be visible to subsequent blocks dispatched to the same queue.” Thus, serial queues are a good way to serializing access to mutable state to avoid race conditions.

    do these tasks finish sequentially as well when using dispatch_async?

    Yes. The queue dictates the execution policy, not how you queue the block.

    In other words, if the queue is serial, queueing with async or sync doesn't change that. The only difference is: do I wait for this block to complete before continuing execution of the rest of the program? dispatch_async=no, dispatch_sync=yes.

    What if task #23 that I submit asynchronously to the serial queue takes a really long time to finish?

    Nothing changes. A serial queue always waits for the previously dequeued block (#23) to complete before dequeuing and executing the next block (#24). If stalling the queue is a concern, you should implement a timeout inside your block code.