I just read this on objc.io Going Fully Asynchronous but can't find good explanation
dispatch_queue_t queueA; // assume we have this
dispatch_sync(queueA, ^(){ // (a)
dispatch_sync(queueA, ^(){ // (b)
foo();
});
});
Once we hit the second dispatch_sync we’ll deadlock: We can’t dispatch onto queueA, because someone (the current thread) is already on that queue and is never going to leave it.
As long as I understand
dispatch_sync
just add the work item (I avoid using the word "block"
as it may confuse) to the queueA, then this work item will be send
to queueA 's target queue, then GCD will preserve a thread
threadWorkItem for this work itemI already read many threads related to this, such as Deadlock with dispatch_sync, Why can't we use a dispatch_sync on the current queue?, Why is this dispatch_sync() call freezing?, ... but can't find good explanation. Some say dispatch_sync
blocks the queue, some say it blocks the current thread, ... :(
So why does it cause deadlock ?
The dispatch_sync
blocks the current thread until the dispatched code finishes, and if you're dispatching synchronously from a serial queue, you therefore are effectively blocking the queue, too. So if you synchronously dispatch from serial queue to itself, it results in a deadlock.
But to be clear, dispatch_sync
blocks the current thread, not the current queue. When dealing with a concurrent queue, a different worker thread will be used for the subsequently dispatched block and no deadlock results.
You appear to be responding to a discussion at the end of the Dispatch Queues chapter of the Concurrency Programming Guide, which says:
Do not call the
dispatch_sync
function from a task that is executing on the same queue that you pass to your function call. Doing so will deadlock the queue. If you need to dispatch to the current queue, do so asynchronously using thedispatch_async
function.
That is not entirely correct. If (a) you are doing this with a concurrent queue; and (b) there are available worker threads, this will not cause a deadlock. But it's a bad practice and should be avoided, nonetheless.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With