Search code examples
swiftconcurrencyswift3

Is DispatchSemaphore a good replacement for NSLock?


I've been using NSLocks 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 DispatchSemaphores 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?


Solution

  • 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/