Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 304
Phlippie Bosman Avatar asked Apr 18 '17 09:04

Phlippie Bosman


People also ask

What is Dispatchsemaphore?

An object that controls access to a resource across multiple execution contexts through use of a traditional counting semaphore.

Does NSLock block the thread?

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.

What is NSLock?

An object that coordinates the operation of multiple threads of execution within the same application.

What is thread-safe in iOS?

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.


2 Answers

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/

like image 89
Ethandf Avatar answered Sep 28 '22 05:09

Ethandf


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.

like image 32
Phlippie Bosman Avatar answered Sep 28 '22 03:09

Phlippie Bosman