并发编程 — Synchronization

在 Swift 中,Synchronization(同步)是指确保多个线程或任务在访问共享资源时不会发生冲突或数据竞争。由于 Swift 是一种支持并发编程的语言,因此在多线程环境下,同步机制尤为重要。

以下是 Swift 中常s用的同步机制和工具:


1. DispatchQueue(串行队列) #

  • 使用串行队列可以确保任务按顺序执行,避免多个线程同时访问共享资源。
  • 通过将任务放在同一个串行队列中,可以实现同步。
let serialQueue = DispatchQueue(label: "com.example.serialQueue")

serialQueue.async {
    // 访问共享资源
}

2. DispatchSemaphore(信号量) #

  • 信号量用于控制对共享资源的访问数量。
  • 通过 wait()signal() 方法实现资源的锁定和释放。
let semaphore = DispatchSemaphore(value: 1)

semaphore.wait() // 锁定资源
// 访问共享资源
semaphore.signal() // 释放资源

3. NSLock(锁) #

  • NSLock 是一个简单的互斥锁,用于保护共享资源。
  • 通过 lock()unlock() 方法实现资源的锁定和释放。
let lock = NSLock()

lock.lock()
// 访问共享资源
lock.unlock()

4. NSRecursiveLock(递归锁) #

  • NSRecursiveLockNSLock 的递归版本,允许同一线程多次锁定资源而不会导致死锁。
let recursiveLock = NSRecursiveLock()

recursiveLock.lock()
// 访问共享资源
recursiveLock.unlock()

5. NSCondition(条件锁) #

  • NSCondition 结合了锁和条件变量,用于线程间的通信和同步。
  • 通过 wait()signal()broadcast() 方法实现线程等待和唤醒。
let condition = NSCondition()

condition.lock()
while !resourceAvailable {
    condition.wait()
}
// 访问共享资源
condition.unlock()

6. @Atomic(属性包装器) #

  • 在 Swift 中,可以通过自定义属性包装器实现原子操作。
  • 例如,使用 OSAtomicDispatchQueue 实现原子性。
@propertyWrapper
struct Atomic<Value> {
    private var value: Value
    private let queue = DispatchQueue(label: "com.example.atomicQueue")

    init(wrappedValue: Value) {
        self.value = wrappedValue
    }

    var wrappedValue: Value {
        get { queue.sync { value } }
        set { queue.sync { value = newValue } }
    }
}

@Atomic var counter: Int = 0

7. Actor(Swift 5.5 引入) #

  • Actor 是 Swift 5.5 引入的一种并发模型,用于解决数据竞争问题。
  • Actor 内部会自动处理同步,确保在同一时间只有一个任务可以访问其状态。
actor Counter {
    private var value = 0

    func increment() {
        value += 1
    }

    func getValue() -> Int {
        return value
    }
}

let counter = Counter()
Task {
    await counter.increment()
    print(await counter.getValue())
}

8. os_unfair_lock(低级锁) #

  • os_unfair_lock 是一种高效的锁,适用于性能敏感的场景。
  • 它是不可递归的,使用时需要小心避免死锁。
var lock = os_unfair_lock()

os_unfair_lock_lock(&lock)
// 访问共享资源
os_unfair_lock_unlock(&lock)

9. Thread Sanitizer(线程检查工具) #

  • 在开发过程中,可以使用 Xcode 的 Thread Sanitizer 工具检测数据竞争和线程安全问题。

总结 #

Swift 提供了多种同步机制,开发者可以根据具体场景选择合适的工具:

  • 对于简单的同步需求,可以使用 DispatchQueueNSLock
  • 对于复杂的并发场景,可以使用 ActorDispatchSemaphore
  • 在性能敏感的场景中,可以考虑使用 os_unfair_lock

在多线程编程中,正确使用同步机制是避免数据竞争和死锁的关键。

本文共 985 字,创建于 Feb 5, 2025
相关标签: Swift, Xcode