美文网首页
swift 的几种锁

swift 的几种锁

作者: 流星阁 | 来源:发表于2024-06-05 15:39 被阅读0次

    1、NSLock

    NSLock 是最基本的锁,提供了传统的锁定和解锁机制。
    场景:在多线程环境下保护一个简单的资源。

    Import Foundation
    class Counter {
        private var value = 0
        private let lock = NSLock()
        
        func increment() {
            lock.lock()
            value += 1
            lock.unlock()
        }
        
        func getValue() -> Int {
            lock.lock()
            let currentValue = value
            lock.unlock()
            return currentValue
        }
    }
    
    let counter = Counter()
    DispatchQueue.concurrentPerform(iterations: 100) { _ in
        counter.increment()
    }
    print("Final counter value: \(counter.getValue())")  // 应该输出:100
    

    2、NSRecursiveLock

    NSRecursiveLock 允许同一线程多次获取同一锁,而不会导致死锁。
    场景:在同一个线程中多次递归调用需要加锁的代码。

    Import Foundation
    
    class RecursiveCounter {
        private var value = 0
        private let lock = NSRecursiveLock()
        
        func increment() {
            lock.lock()
            value = recursiveIncrement(value: value)
            lock.unlock()
        }
        
        private func recursiveIncrement(value: Int) -> Int {
            lock.lock()
            defer { lock.unlock() }
            
            if value < 10 {
                return recursiveIncrement(value: value + 1)
            } else {
                return value
            }
        }
        
        func getValue() -> Int {
            lock.lock()
            let currentValue = value
            lock.unlock()
            return currentValue
        }
    }
    
    let recursiveCounter = RecursiveCounter()
    recursiveCounter.increment()
    print("Final counter value: \(recursiveCounter.getValue())")  // 应该输出:10
    

    3、NSCondition / NSConditionLock

    NSCondition 结合了锁和条件变量,适用于需要线程等待某个特定条件满足的情况。
    场景:一组线程需要等待某个特定条件满足才能继续执行。

    Import Foundation
    
    class DataBuffer {
        private var buffer: [Int] = []
        private let condition = NSCondition()
        
        func produce(value: Int) {
            condition.lock()
            buffer.append(value)
            condition.signal() // 唤醒等待该条件的线程
            condition.unlock()
        }
        
        func consume() -> Int? {
            condition.lock()
            while buffer.isEmpty {
                condition.wait() // 等待直到有数据可消费
            }
            let value = buffer.removeFirst()
            condition.unlock()
            return value
        }
    }
    
    let buffer = DataBuffer()
    DispatchQueue.global().async {
        for i in 0..<10 {
            buffer.produce(value: i)
            sleep(1)  // 模拟生产延迟
        }
    }
    
    DispatchQueue.global().async {
        for _ in 0..<10 {
            if let value = buffer.consume() {
                print("Consumed: \(value)")
            }
        }
    }
    
    import Foundation
    
    // 定义一个用于存储数据的简单类
    class SharedResource {
        var data: [String] = []
        var conditionLock = NSConditionLock(condition: 0) // 初始条件为0
    }
    
    let sharedResource = SharedResource()
    
    // 生产者线程
    let producer = Thread {
        for i in 1...5 {
            sharedResource.conditionLock.lock(whenCondition: 0)
            print("Producer: Producing item \(i)")
            sharedResource.data.append("Item \(i)")
            sharedResource.conditionLock.unlock(withCondition: 1) // 生产完成,更新条件
            sleep(1) // 模拟生产时间
        }
    }
    
    // 消费者线程
    let consumer = Thread {
        for _ in 1...5 {
            sharedResource.conditionLock.lock(whenCondition: 1)
            if let item = sharedResource.data.first {
                print("Consumer: Consuming \(item)")
                sharedResource.data.removeFirst()
            }
            sharedResource.conditionLock.unlock(withCondition: 0) // 消费完成,更新条件
            sleep(2) // 模拟消费时间
        }
    }
    
    // 启动生产者和消费者线程
    producer.start()
    consumer.start()
    
    // 等待线程完成
    producer.join()
    consumer.join()
    
    print("All items processed.")
    

    4、DispatchSemaphore

    DispatchSemaphore 提供了一种基于计数信号量的线程同步机制。
    场景:控制同一时间只能有指定数量的线程访问某个资源。

    Import Dispatch
    let semaphore = DispatchSemaphore(value: 3)
    for i in 0..<10 {
        DispatchQueue.global().async {
            semaphore.wait() // 等待信号量
            print("Task \(i) started.")
            sleep(2) // 模拟任务执行
            print("Task \(i) finished.")
            semaphore.signal() // 释放信号量
        }
    }
    

    5、DispatchQueue (穿行队列)

    使用 GCD (Grand Central Dispatch) 的串行队列,可以确保队列中的任务按顺序执行,从而实现线程安全。
    场景:按顺序执行任务,保护资源访问。

    Import Dispatch
    let serialQueue = DispatchQueue(label: "com.example.myserialqueue")
    var sharedResource = [Int]()
    for i in 0..<10 {
        serialQueue.async {
            sharedResource.append(i)
            print("Appended \(i)")
        }
    }
    

    6、os_unfair_lock

    os_unfair_lock 是一种低级、高性能的锁,适用于需要较高性能的锁操作环境。
    场景:需要高性能且明确知道只在较短代码段中使用锁。

    import os.lock
    
    class UnfairLockCounter {
        private var value = 0
        private var lock = os_unfair_lock_s()
        
        func increment() {
            os_unfair_lock_lock(&lock)
            value += 1
            os_unfair_lock_unlock(&lock)
        }
        
        func getValue() -> Int {
            os_unfair_lock_lock(&lock)
            let currentValue = value
            os_unfair_lock_unlock(&lock)
            return currentValue
        }
    }
    
    let unfairCounter = UnfairLockCounter()
    DispatchQueue.concurrentPerform(iterations: 100) { _ in
        unfairCounter.increment()
    }
    print("Final counter value: \(unfairCounter.getValue())")  // 应该输出:100
    

    7、@ synchronized

    Swift 本身没有直接的 @synchronized 关键字,但可以通过扩展 NSObject 来实现类似的功能。

    Import Foundation
    func synchronized (_ lock: AnyObject, closure: () -> Void) {
        objc_sync_enter(lock)
        closure()
        objc_sync_exit(lock)
    }
    let lockObject = NSObject()
    synchronized(lockObject) {
        // 需要保护的代码区域
    }
    

    8、swift 5.5 可以使用actor来保证线程同步问题

    可以参考:https://www.bennyhuo.com/2022/01/22/swift-coroutines-04-structured-concurrency/

    相关文章

      网友评论

          本文标题:swift 的几种锁

          本文链接:https://www.haomeiwen.com/subject/nzvuqjtx.html