Current count value of DispatchSemaphore

144 views Asked by At

DispatchSemaphore used to restrict the concurrent access on shared resources. It pauses the thread using counter value. Is it possible to get that counter value?

1

There are 1 answers

0
Rob On

You can print the semaphore.debugDescription or use debugPrint:

let semaphore = DispatchSemaphore(value: 3)
debugPrint(semaphore)                      // <OS_dispatch_semaphore: semaphore[0x6000024dd590] = { xref = 2, ref = 1, port = 0x0, value = 3, orig = 3 }>
semaphore.wait()
debugPrint(semaphore)                      // <OS_dispatch_semaphore: semaphore[0x6000024dd590] = { xref = 2, ref = 1, port = 0x0, value = 2, orig = 3 }>
semaphore.wait()
debugPrint(semaphore)                      // <OS_dispatch_semaphore: semaphore[0x6000024dd590] = { xref = 2, ref = 1, port = 0x0, value = 1, orig = 3 }>
semaphore.signal()
debugPrint(semaphore)                      // <OS_dispatch_semaphore: semaphore[0x6000024dd590] = { xref = 2, ref = 1, port = 0x0, value = 2, orig = 3 }>
semaphore.signal()
debugPrint(semaphore)                      // <OS_dispatch_semaphore: semaphore[0x6000024dd590] = { xref = 2, ref = 1, port = 0x0, value = 3, orig = 3 }>

Use this for diagnostic purposes, only, though. They deliberately did not expose this counter value as a property.


For what it is worth, I might advise against using semaphores to “restrict the concurrent access on shared resources.” Generally, we would prefer other patterns such as actors, locks, serial GCD queues, or the reader-writer pattern.

I also might advise against semaphores to “avoid the thread explosion.” Again, there are better, more contemporary patterns ranging from GCD’s concurrentPerform, OperationQueue and its maxConcurrentOperationCount, the cooperative thread pool of Swift concurrency, Combine’s “max publishers” pattern, etc. (FWIW, most of these patterns do not expose the “current count” either.)

In short, many consider semaphores to be a bit of an anti-pattern, nowadays. But if you want to see the count, debugPrint (or explicitly accessing the debugDescription) will show you what’s going on.