What is the difference (advantage and disadvantage) between using DispatchGroup
and NSRecursiveLock
?
It looks like they are doing exactly the same thing.
What is the difference (advantage and disadvantage) between using DispatchGroup
and NSRecursiveLock
?
It looks like they are doing exactly the same thing.
Locks and groups serve very different purposes. When dealing with a series of concurrent tasks:
A lock generally is used to prevent/block these tasks from simultaneously interacting with some shared, non thread-safe, resource.
A group is generally used for identifying when these concurrent tasks are all complete (regardless of the order in which they finished).
For example, if processing a series of images in parallel, you might use a lock or similar mechanism to update some property (e.g. the array of the results), whereas the dispatch groups is used to know when all of these concurrent tasks are done.
The primary difference is that DispatchGroup
is closer to a counting semaphore with a callback, whereas an NSLock
is a simple mutex.
For instance, a DispatchGroup
can be enter
ed more than once, by one or more threads, and enter
ing a DispatchGroup
will never block the calling thread. The calling threads are also responsible for balancing each enter
call with a call to leave
. If there is a notify
callback registered on the group, it will execute once the number of enter
s minus the number of leave
s reaches 0. A good example of using a DispatchGroup
would be to make multiple network requests and have a single piece of callback code be executed after all the network requests have completed (or timed out, etc).
However, if one thread lock
s an NSLock
, any other thread (or even the same thread, for that matter) tries to lock
it again before it is unlock
ed, the second thread will be blocked until it is unlock
ed (and possibly never, if you try to lock
it twice from the same thread). A good example of using an NSLock
is to provide multi-threaded access to a single, mutable piece of data. In this case, multiple threads can be sure to get coherent reads and writes to/from the mutable storage without potentially trampling one another.
NSLock
(and mutexes in general) are a much lower level synchronization primitive than a DispatchGroup
. In general, you should always use the highest level primitive that achieves your goal. If a DispatchGroup
will do the job, use it, and ignore NSLock
.