You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:39:05