各种与并发相关的工具,包括锁和异步流的补充等等。
dependencies: [
.package(url: "https://github.com/ordo-one/package-concurrency-helpers", .upToNextMajor(from: "0.0.1")),
]
然后将依赖项添加到你的目标,例如:
.executableTarget(
name: "MyExecutableTarget",
dependencies: [
.product(name: "SwiftConcurrencyHelpers", package: "package-concurrency-helpers")
]),
从异步上下文安全地调用阻塞函数
let result = await forBlockingFunc {
// Call your blocking function here.
}
在非异步上下文中运行异步代码
let result = runSync {
await someFunction()
}
简单的锁,包括一个在等待锁时休眠的变体
let lock = Lock()
let result = lock.withLock {
…
}
...以及一个旋转等待锁的变体
let lock = Spinlock()
let result = lock.withLock {
… // Make sure whatever you do here is quick; other threads may be busy waiting.
}
一个简单的线程安全的值容器
let safeValue = Protected(myValue)
safeValue.write {
// Have exclusive access to the contents here.
$0.someField = true
}
safeValue.read {
// Have exclusive, read-only access to the contents here.
if $0.someField {
…
}
}
一个用于值类型的不安全的 Sendable
包装器
var someNonSendable = …
let wrapper = UnsafeTransfer(someNonSendable)
Task.detached {
let value = wrapper.wrappedValue
// Use `value` here, instead of the original name `someNonSendable`.
}
还有一个用于可变值的 UnsafeMutableTransfer
变体。
将一个值 yield 到一个带有背压支持的 AsyncStream
(以并发安全的方式等待,直到流准备好接收消息)
guard yieldWithBackPressure(message: …, to: continuation) else {
// Stream was closed or this task has been cancelled.
}
一个用于值类型的简单引用类型容器
let a = Box(5)
let b = a
b.value += 1
// 'b' and 'a' both now hold 6.
它继承了包含类型的 Equatable
、Comparable
、CustomStringConvertible
和 CustomDebugStringConvertible
一致性。
确定是否附加了调试器(Apple C 语言 AmIBeingDebugged
的 Swift 版本)
if isBeingDebugged {
// Running under, or attached by, a debugger of some kind.
} else {
// *Probably* not being debugged.
}
请注意,这并非万无一失;调试器可以隐藏自己,使其无法被检测到。
Apple AsyncStream.makeStream(of:bufferingPolicy:) 的一个反向移植,使其在 Swift 5.8 及更早版本中也可用。
计算大于给定整数的下一个最高 2 的幂
let roundedUp = nearestPowerOf2(27)
// 'roundedUp' is 32.
跟踪事件的速率,并在每 N 个事件时运行一个闭包
let monitor = ProcessingRate(interval: 10)
while true {
monitor.checkpoint {
// Runs every 10 calls to `checkpoint`.
print("Current rate: \(monitor.ratePerSecond) Hz")
}
}
计数事件,然后在指定的检查点运行一个闭包,如果自上次重置以来(如果之前从未重置,则自计数器创建以来)已经过去了设定的持续时间,则重置计数。
let monitor = TimeIntervalCounter(clock: ContinuousClock(),
timeInterval: .seconds(5))
while true {
if monitor.incremenet() {
// It has been at least five seconds since the monitor was last reset.
}
monitor.checkpoint {
// Runs at most once every five seconds.
print("Current count: \(monitor.count)")
// The count will automatically be reset to zero when this closure exits.
}
}