一些原子函数,可用于 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 或更高版本。