能否获取DispatchSemaphore的当前计数器值?
DispatchSemaphore 能否获取当前计数器值?
不行——苹果没有给 DispatchSemaphore 提供公开的官方接口来直接读取它的内部计数器值。
之所以这么设计,是因为在多线程并发场景下,直接读取计数器的瞬间值没有实际意义:你刚拿到数值,可能下一秒就被其他线程的 wait() 或 signal() 操作修改了,不仅无法保证准确性,还可能因为竞态条件引发问题。
如果你的业务确实需要追踪计数器的状态,可以自己封装一层逻辑,用线程安全的方式维护一个镜像计数器:
- 用串行
DispatchQueue或者原子操作(比如OSAtomic系列函数)来管理一个自定义变量 - 每次调用原 semaphore 的
wait()后,同步递减自定义计数器;每次调用signal()后,同步递增它 - 这个自定义变量就能安全读取,作为原 semaphore 计数器的近似值
举个 Swift 示例:
class TrackedSemaphore { private let semaphore: DispatchSemaphore private let syncQueue = DispatchQueue(label: "tracked.semaphore.queue") private var trackedCount: Int init(initialValue: Int) { semaphore = DispatchSemaphore(value: initialValue) trackedCount = initialValue } func wait(timeout: DispatchTime = .distantFuture) -> DispatchTimeoutResult { let result = semaphore.wait(timeout: timeout) syncQueue.sync { if result == .success { trackedCount -= 1 } } return result } func signal() -> Int { let signalResult = semaphore.signal() syncQueue.sync { if signalResult == 0 { trackedCount += 1 } } return signalResult } func currentCount() -> Int { return syncQueue.sync { trackedCount } } }
小提醒:自定义计数器和原 semaphore 的内部状态可能存在极短暂的不一致(比如在 semaphore 操作完成后、自定义计数器更新前被读取),但对于绝大多数需要追踪状态的场景来说,这个延迟可以忽略。
内容的提问来源于stack exchange,提问作者iroh
相关产品推荐
相关产品推荐

