iOS常见的锁机制、示例及原理分析

467 阅读2分钟

在iOS开发中,多线程安全是关键问题,锁机制用于保护临界区资源。以下是常见的锁机制、示例及原理分析:


1. NSLock(互斥锁)

  • 原理:基于pthread_mutex的封装,非递归锁。线程在获取锁失败时会休眠,等待唤醒。

  • Objective-C

    NSLock *lock = [[NSLock alloc] init];
    [lock lock];
    // 临界区代码
    [lock unlock];
    
  • Swift

    let lock = NSLock()
    lock.lock()
    defer { lock.unlock() }
    // 临界区代码
    

2.  @synchronized

  • 原理:基于objc_sync_enterobjc_sync_exit的递归锁,以传入对象为锁标识。

  • Objective-C

    @synchronized(self) {
        // 临界区代码
    }
    
  • Swift(需手动调用):

    objc_sync_enter(self)
    defer { objc_sync_exit(self) }
    // 临界区代码
    

3. DispatchSemaphore(信号量)

  • 原理:通过计数器控制访问,wait()减1,signal()加1,计数器为0时阻塞。

  • Objective-C

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // 临界区代码
    dispatch_semaphore_signal(semaphore);
    
  • Swift

    let semaphore = DispatchSemaphore(value: 1)
    semaphore.wait()
    defer { semaphore.signal() }
    // 临界区代码
    

4. os_unfair_lock(替代OSSpinLock)

  • 原理:低级锁,解决优先级反转问题,需手动管理,不可递归。

  • Objective-C

    #import <os/lock.h>
    os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
    os_unfair_lock_lock(&lock);
    // 临界区代码
    os_unfair_lock_unlock(&lock);
    
  • Swift

    var lock = os_unfair_lock()
    os_unfair_lock_lock(&lock)
    defer { os_unfair_lock_unlock(&lock) }
    // 临界区代码
    

5. pthread_mutex(POSIX互斥锁)

  • 原理:跨平台互斥锁,支持配置递归属性。

  • Objective-C

    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_lock(&mutex);
    // 临界区代码
    pthread_mutex_unlock(&mutex);
    pthread_mutex_destroy(&mutex);
    
  • Swift(需桥接或使用C API)。


6. NSRecursiveLock(递归锁)

  • 原理:允许同一线程多次加锁,避免死锁。

  • Objective-C

    NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
    [lock lock];
    [lock lock]; // 重复加锁
    // 临界区代码
    [lock unlock];
    [lock unlock];
    
  • Swift

    let lock = NSRecursiveLock()
    lock.lock()
    defer { lock.unlock() }
    // 可重复加锁
    

7. NSCondition(条件锁)

  • 原理:结合锁和条件变量,用于线程间通信。

  • Objective-C

    NSCondition *condition = [[NSCondition alloc] init];
    [condition lock];
    while (!ready) [condition wait];
    // 执行操作
    [condition unlock];
    
  • Swift

    let condition = NSCondition()
    condition.lock()
    defer { condition.unlock() }
    while !ready { condition.wait() }
    // 执行操作
    

锁的选择与性能

  • 性能排序os_unfair_lock > pthread_mutex > NSLock > @synchronized
  • 自旋锁OSSpinLock因优先级反转被弃用,改用os_unfair_lock
  • 递归需求:使用NSRecursiveLock或配置pthread_mutex为递归属性。
  • 线程通信:使用NSConditionDispatchSemaphore

注意事项

  1. 避免在锁内调用外部代码,防止死锁。
  2. 确保加锁和解锁成对出现,使用defer(Swift)保证解锁。
  3. 不要跨线程解锁os_unfair_lock,可能导致崩溃。

通过合理选择锁机制,可提升多线程安全性和性能。