dispatch_async vs dispatch_sync execution order

Andrew picture Andrew · Jan 12, 2013 · Viewed 7.1k times · Source

I have a serial dispatch queue created with:

dispatch_queue_t serialQueue = dispatch_queue_create("com.unique.name.queue", DISPATCH_QUEUE_SERIAL);

I want to use this serial queue to ensure thread safety for class access, while automatically doing work asynchronously that doesn't need to return to the calling thread.

- (void)addObjectToQueue:(id)object
{
    dispatch_async(serialQueue, ^{
        // process object and add to queue
    }); 
}

- (BOOL)isObjectInQueue:(id)object
{
    __block BOOL returnValue = NO;
    dispatch_sync(serialQueue, ^{
        // work out return value
    });
    return returnValue;
} 

If I call the addObjectToQueue: method, then immediately call the isObjectInQueue: method, are they guaranteed to be executed in the same order, or will/could the isObjectInQueue execute first?

In other words, does dispatch_async perform exactly the same as dispatch_sync (scheduling the block immediately) except that it doesn't block the calling thread?

I have seen similar questions with answers going both ways, so I am looking for a definitive answer, preferably backed with Apple documentation.

Answer

mattjgalloway picture mattjgalloway · Jan 12, 2013

Are they guaranteed to be executed in the same order?

Yes.

Will / could the isObjectInQueue execute first?

Yes.

The reason for the yes to both answers is you should consider threading. Which is presumably why you are using the serial queue in the first place. You are making access to that queue thread safe.

Basically, the blocks will execute in the order in which they are put on the serial queue. That is 100% guaranteed. However, if multiple threads are hammering away at this then one thread may get in first to read something from the queue before another has had chance to add it.

In other words, does dispatch_async perform exactly the same as dispatch_sync (scheduling the block immediately) except that it doesn't block the calling thread?

That's right. In both cases the block is added to the queue. It is added immediately. dispatch_sync just waits for the block to finish before returning whereas dispatch_async returns immediately.