iOS Swift中是否存在与Ruby Concurrent::Event功能对等的实现?
Swift中对应Ruby Concurrent::Event的实现方案
在iOS Swift生态中完全可以实现和Concurrent::Event功能完全一致的并发原语,支持「初始为未触发状态、等待操作阻塞、单次触发后永久生效并唤醒所有等待线程、后续等待操作直接返回」的所有特性,你可以根据自己使用的技术栈选择对应方案:
方案1:基于GCD的线程阻塞版实现(兼容所有iOS版本)
我们可以基于DispatchGroup简单封装得到完全匹配行为的Event类,使用方式和Ruby版本完全一致:
import Foundation class Event { private let group = DispatchGroup() private var isSet: Bool = false private let lock = NSLock() init() { // 初始进入未触发状态 group.enter() } /// 阻塞当前线程直到事件被触发 func wait() { group.wait() } /// 触发事件,唤醒所有等待线程,且后续调用wait会直接返回 func set() { lock.lock() defer { lock.unlock() } // 避免重复触发导致崩溃 guard !isSet else { return } isSet = true group.leave() } }
示例用法
和你给出的Ruby示例逻辑完全一致:
let event = Event() let t1 = Thread { print("t1 is waiting") event.wait() print("event occurred") } let t2 = Thread { print("t2 calling set") event.set() } t1.start() t2.start() t1.join() t2.join()
运行输出和Ruby版本表现一致,多线程调度下输出顺序可能有变化,但*"t2 calling set"永远早于"event occurred"输出*。
方案2:基于Swift Concurrency的异步挂起版实现(iOS 13+)
如果你使用Swift 5.5+的async/await原生并发模型,也可以封装不需要阻塞线程的异步版本Event:
import Foundation @available(iOS 13.0, macOS 10.15, *) class AsyncEvent { private var isSet: Bool = false private var pendingContinuations: [CheckedContinuation<Void, Never>] = [] private let lock = NSLock() /// 挂起当前协程直到事件被触发 func wait() async { lock.lock() if isSet { lock.unlock() return } await withCheckedContinuation { continuation in pendingContinuations.append(continuation) lock.unlock() } } /// 触发事件,恢复所有挂起的协程,且后续调用wait会直接返回 func set() { lock.lock() guard !isSet else { lock.unlock() return } isSet = true let continuations = pendingContinuations pendingContinuations.removeAll() lock.unlock() continuations.forEach { $0.resume() } } }
示例用法
let event = AsyncEvent() Task { print("t1 is waiting") await event.wait() print("event occurred") } Task { print("t2 calling set") event.set() }
内容的提问来源于stack exchange,提问作者andrewdotn
相关产品推荐
相关产品推荐

