vishdeshmukh
(Vishwanath Deshmukh)
1
Wait() and Signal() would be used to decrement and increment semaphore count. But how to know semaphore's current count?
let semaphore = DispatchSemaphore(value: 3)
var name = "Vishwanath"
/*
How to apply check condition here:
if semaphore count is less than or equal to 3, then only proceed else print saying no recourse available currently and return
guard semaphore.count <= 3 else {
print("No resource available")
return
}
*/
semaphore.wait()
name = "Vish Deshmukh"
semaphore.signal()
Lantua
2
There's no way to check, but you can wait with zero-second timeout multiple times.
ksluder
(Kyle Sluder)
3
There’s no API for this because it is an inherently racy condition. As soon as you check, your thread could be interrupted and other threads can increment or decrement the semaphore.
1 Like
vishdeshmukh
(Vishwanath Deshmukh)
4
I tried with following but it executes timeout quickly for first 3 statements and returns. Only fourth check work so I am not sure how to use it correctly.
if semaphore.wait(timeout: .now()) == .success {
print("ERROR")
return
}
Counting semaphores are designed so that wait succeeds if it can decrement and still leave the count non-negative. That's just how they work; there is no way to have wait instead succeed only if the count would be <= 3. To use them, you have to find a way to fit your problem around that constraint. If you can't find a way to do that, then you will need to fall back on the more general technique of using a lock and (possibly) a condition variable.
With that said, though, as a general rule, you should try to avoid condition variables and semaphores, because they are susceptible to unavoidable priority inversions. They're only really acceptable if you're always using a zero timeout and so will never block, but if you're doing that, you don't need a semaphore in the first place and can just use a simple atomic.
5 Likes