一些原子函数,可用于 Swift 3.1 及更高版本,包括 Swift 5.3
本项目将 Clang 的 C11 原子操作支持的子集桥接到 Swift,并且与 SE-0282 兼容。 自 2017 年以来,此软件包一直是长期存在(但现在已弃用)的 SwiftAtomics 软件包的底层核心。
CAtomics 使用 C 风格的接口为 Swift 提供原子操作。 CAtomics 实现了以下类型:
AtomicRawPointer,AtomicMutableRawPointer,AtomicOpaquePointer 以及 Optional 指针的版本 (AtomicOptionalRawPointer 等);AtomicInt 和 AtomicUInt,以及 8 位、16 位、32 位和 64 位整数类型的有符号和无符号版本;AtomicBool在 CAtomics 中定义的函数都以 CAtomics 为前缀。 所有类型都定义了 CAtomicsLoad,CAtomicsStore,CAtomicsExchange,CAtomicsCompareAndExchangeWeak 和 CAtomicsCompareAndExchangeStrong。 此外,整数类型还定义了 CAtomicsAdd,CAtomicsSubtract,CAtomicsBitwiseAnd,CAtomicsBitwiseOr 和 CAtomicsBitwiseXor。 最后,AtomicBool 定义了 CAtomicsAnd,CAtomicsOr 和 CAtomicsXor。
可以使用每个方法上的 order: MemoryOrder 参数来设置内存排序 (来自 <stdatomic.h>)。
public enum MemoryOrder : UInt32 {
case relaxed, acquire, release, acqrel, sequential
}
请注意,memory_order_consume 在此模块中没有等效项,因为(据我所知) clang 默默地将该排序升级为 memory_order_acquire,从而(目前)无法测试算法是否可以正确使用 memory_order_consume。 这也意味着它的缺失没有任何损失。
原子类型可用作线程之间的同步点,因此与 Swift 的互斥性检查具有有趣的关系。 它们应该在固定的内存位置初始化,例如引用类型的成员、被闭包捕获的变量或堆分配。 也就是说,虽然前两个在使用当前 Swift 时可以按预期工作,但只有后者(堆分配)与线程清理器兼容。
为了以线程清理器可接受的方式使用原子变量,必须使用 UnsafeMutablePointer 为原子变量分配内存。 然后,根据需要将该指针传递给 CAtomics 模块中定义的函数。
import CAtomics
class Example {
private var counter = UnsafeMutablePointer<AtomicInt>.allocate(capacity: 1)
init() {
CAtomicsInitialize(counter, 0)
}
deinit {
counter.deallocate()
}
func increment(by value: Int = 1) {
CAtomicsAdd(counter, value, .relaxed)
}
}
此库需要 Swift 3.1 或更高版本。 在 Linux 上,它还需要 Clang 3.6 或更高版本。