I've been using NSLock
s to synchronize touchy parts of code, but have been running into issues due to the fact that they must be unlocked from the same thread that they were locked from. Then I found that GCD's DispatchSemaphore
s seem to do the same thing, with the added convenience that they can be signaled from any thread. I was wondering, though, if this convenience comes at the price of thread-safety. Is it advisable to replace
let lock = NSLock()
lock.lock()
// do things...
lock.unlock()
with
let semaphore = DispatchSemaphore(value: 1)
semaphore.wait()
// do things...
semaphore.signal()
or will I run into issues regarding thread-safety anyway?
An object that controls access to a resource across multiple execution contexts through use of a traditional counting semaphore.
Yes, it's safe to use NSLock from any thread, including the main thread. The only constraint with NSLock is that you must unlock it from the same thread that you locked it, which you are doing here.
An object that coordinates the operation of multiple threads of execution within the same application.
Thread Safety APIs in iOSBy creating a queue of tasks where only one task can be processed at any given time, you are indirectly introducing thread safety to the component that is using the queue.
Yes they have the same function, both to deal with producer-consumer problem.
Semaphore allows more than one thread to access a shared resource if it is configured accordingly. You can make the execution of the blocks in the same concurrent dispatchQueue.
{
semaphore.wait()
// do things...
semaphore.signal()
}
Actually the same applies to Lock, if you only want one thread to touch the resource at one time, in the concurrent way.
I found this to be helpful: https://priteshrnandgaonkar.github.io/concurrency-with-swift-3/
Since asking this, I have mostly switched over to another way of locking blocks of code: serial dispatch queues. I use it like this:
let queue = DispatchQueue(label: "<your label here>")
queue.async {
// do things...
}
The queue is serial by default, meaning it acts as a lock that releases when the block is exited. Therefore, it's not appropriate if you need to lock on an asynchronous operation, but it works a charm in most cases.
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